Androidでソケット通信 Java(Android)からC++へ
Android端末でソケット通信ができるようになったのでメモ
Androidでソケット通信を行う際は、AndroidManifest.xmlにパーミッションを通す必要があります。
packageとapplicationの間に
<uses-permission android:name="android.permission.INTERNET" />
を追記すればOKです。
あと、通信などの重たい処理をする際はUIスレッドとは別のスレッドで処理を行わなければなりません。AsyncTaskで非同期処理させないと止められてしまうので注意です。
Android側のソースコード(MainActivity.java)
package ..... import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button sendImageButton = findViewById(R.id.sendImageButton); sendImageButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { byte src_img[] = {10, 20, 30}; SocketThread sockTask = new SocketThread(src_img); sockTask.execute(); } }); } }
Android側のソースコード(SocketThread.java)
package ...... import android.os.AsyncTask; import java.io.DataOutputStream; import java.io.OutputStream; import java.net.Socket; public class SocketThread extends AsyncTask<Integer, Integer, Integer> { byte src_img[]; SocketThread(byte src_img[]){ this.src_img = new byte[src_img.length]; this.src_img = src_img; } @Override protected Integer doInBackground(Integer... src_img){ String server = "";//自分の環境のアドレス int port = 12345; try{ //ソケット通信 Socket sock = new Socket(server, port); OutputStream os = sock.getOutputStream(); DataOutputStream dos = new DataOutputStream(os); //送信部分 //送信するデータがbyte型なのでwrite一回でも送信できます for(int i = 0; i < this.src_img.length; i++) { System.out.println(i + "回目 " + this.src_img[i]); dos.write(this.src_img[i]); dos.flush(); } dos.close(); sock.close(); }catch(Exception e){ e.printStackTrace(); } return 0; } }
ジェネリクス(<Integer, Integer, Integer>のこと)は配列を扱えないらしく、execute(10, 20, 30);という風にいれないといけないらしいです。
なので、インスタンス生成する際にSocketThreadのsrc_imgに値を代入しておくことにしました。画像データの時もこれでいけると思います。
サーバ側のソースコード(SocketThread.cpp)
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <netinet/in.h> void print_Array(unsigned char buf[]){ printf("受信内容 : "); for(int i = 0; i < sizeof(buf); i++){ printf("%d, ", buf[i]); } printf("\n\n"); } int main(){ int sock0; int sock; struct sockaddr_in addr; struct sockaddr_in client; socklen_t len; sock0 = socket(AF_INET, SOCK_STREAM, 0); addr.sin_family = AF_INET; addr.sin_port = htons(12345); addr.sin_addr.s_addr = INADDR_ANY; bind(sock0, (struct sockaddr *)&addr, sizeof(addr)); listen(sock0, 5); len = sizeof(client); sock = accept(sock0, (struct sockaddr *)&client, &len); unsigned char src_img[24]; sleep(1); int result = recv(sock, &src_img, sizeof(src_img), 0); if(result != -1){ printf("正常に受信できました。\n"); printf("受信したバイト数 = %d\n", result); print_Array(src_img); }else{ printf("受信できませんでした。\n"); printf("受信した文字数 = %d\n", result); print_Array(src_img); } close(sock0); close(sock); return 0; }
C++のほうはいたって普通のもので大丈夫です。