Contents
目標
PC⇔Android間の通信を技術的に調べたいと思っていました。今回はその2回目、 PC⇔Android間のソケット通信をWi-Fi経由で行います。 ソケット通信 に関しては、今回で終えたいところです。前回は前段階として、PC⇔PC間のソケット通信の調査を行いました。こんな感じでWi-Fi経由でデータを送受信できることを確認します。
実際にやってみた・テキスト編
AndroidでSocket通信のサンプルの作成[クライアント]
Android端末同士でSocketとDatagramSocketを使用する のサンプルを参考にさせて頂き、Kotlinに書きなおしました。パーミッションの”internet”は忘れないように、必ずManifestに追加してください。
① kotlin extensionsを使って便利にしましょう。spiner,button,edit_textで使用しています。
② Socketのポートは60001にして、C#側のサンプルと合わせています。
package com.example.and_sock_client import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.widget.ArrayAdapter // ① kotlin extensionsはもちろん使用 import kotlinx.android.synthetic.main.activity_main.* import java.net.InetSocketAddress import android.os.AsyncTask import java.io.BufferedWriter import java.io.IOException import java.io.OutputStreamWriter import java.net.Socket import java.net.SocketException class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // IPアドレス設定 0 ~ 255 Start----------------------------------- val items = arrayOfNulls<String>(256) var ii: Int = 0 while (ii < 256) { items[ii] = ii.toString() ii++ } val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, items) // ① spinner1.adapter = adapter spinner2.adapter = adapter spinner3.adapter = adapter spinner4.adapter = adapter // IPアドレス設定 0 ~ 255 End------------------------------------ // IPアドレスの初期値設定 192.168.0.0 spinner1.setSelection(192) spinner2.setSelection(168) spinner3.setSelection(0) spinner4.setSelection(0) button_send.setOnClickListener() { val IPAddress = spinner1.selectedItem.toString() + '.'.toString() + spinner2.selectedItem.toString() + '.'.toString() + spinner3.selectedItem.toString() + '.'.toString() + spinner4.selectedItem.toString() // ② ポートはC#側とあわせています。 // ソケット通信用にポート設定。送信したいデータとIPアドレス設定。 val inetSocketAddress = InetSocketAddress(IPAddress, 60001) // Androidではソケット通信は別スレッドで非同期通信。 val task = object : AsyncTask<InetSocketAddress, Void, Void>() { override fun doInBackground(vararg inetSocketAddresses: InetSocketAddress): Void? { var socket: Socket? = null try { // 接続 socket = Socket() socket!!.connect(inetSocketAddresses[0]) val writer = BufferedWriter(OutputStreamWriter(socket!!.getOutputStream())) // ① kotolin extensionsで便利。 // データを送信。 writer.write(edit_text.text.toString()) // クローズ writer.close() socket!!.close() } catch (e: SocketException) { e.printStackTrace() } catch (e: IOException) { e.printStackTrace() } return null } } task.execute(inetSocketAddress) } } }
実行してみると以下のような形になります。
別PC側のサンプル[サーバ]
前回作成したサンプルをそのまま流用しました。うまくいくかどうかはやってみないとわからなかったが、そのままで何事もなくサクッと使用できました。
[同一PC] PC⇔Android(エミュレータ)の通信
同じPC内で、試しにC#側のソフトと通信させてみたら、意外にサクッと通信できました。エミュレータのポートをtelnet/redirとかしないといけないかと思っていましたが、何もせずに外部とつながれられるようです。edit_text.toString()みたいにしていたので、変な文字列が出ていました。
PCは Surface Pro Win10 Home Andorid開発用
赤線の部分です。データとしては、テキストではなedit_textをデータ化したものが送られていました。(コーディングミス)
正しく作ったサンプルは以下のようになります。 Androidのサンプルをedit_text.text.toString() に変更してやると以下の様に通信できていることが確認できました。
赤線部分、今度はテキストが送信されています。
[別PC] PC⇔Android(エミュレータ)の通信
じゃあ、パソコンを2台使用してもいけるのをテストしてみました。意外にサクッと通信できて、こんな楽だったのって感じでした。
Android エミュレータ @ PC 1 ( Surface Pro, Win10 )
C# Server側ソフトはそのまま流用 @ PC2 ( Win on Mac, Win10)
上記のPC1からの文字列がそのままPC2側に Wifiを通じて通信できています。やった!
赤線部分、意図したテキストが送られています。
感想
もうちょいむずかしいのかと思ってただけに 思っていたより簡単に通信してくれていたので、実機の転送せずにサクッと実現できて拍子抜けしました。実機での場合もほとんどこのままかと思いますので、今回はパス。(IPアドレス一覧アプリなど使用すれば、IPアドレスも簡単に取得できかと思います。)
参考リンク
ここまでの内容は以下のリンクを参考にさせてもらいながら、PC⇔Android間のソケット通信のテストを行いました。
- Android端末同士でSocketとDatagramSocketを使用する (@sourcekatuさん)
- Kotlin UDP ソケット通信 (@unpiさん)
- [ Android ] TCP・UDP通信 (メモ置き場さん)
たぶんサーバでのソケット通信に関してだと思うけど、トラブった時のために頭の片隅に置いておきます。Android のセキュリティ向上のための一環。
- Android 9でHTTP通信を有効にする方法 ( fuka さん)
- Android 9(Pie)でHTTP通信を有効にする (@b_a_a_d_oさん)
- Android P で TLS のデフォルト化によるユーザー保護 (Google Developers)