Wifi接続によるsocket通信

2,918 views
Skip to first unread message

だい

unread,
Feb 11, 2014, 3:17:11 AM2/11/14
to android-g...@googlegroups.com
お世話になっております。android端末と自作APを接続したWifi機器をwifi接続して、socket接続によって通信し、データのやりとりを行っています。
Wifi機器は一定の時間間隔でデータを送信する動作をさせ、android端末でそのデータを受信し、Logcat表示しています。

android端末は仕様上、データが送信されてくるタイミングの間だけ、wifi・socketによる通信経路を作り、データを受信して、その以外はwifi接続自体を切りたいです。
現在、問題として、上記のようにWifi・socket接続⇔Wifi・socket切断の動作でデータ受信を行うと、Wifi機器から送られてくるデータを受け取らない状態がたまに発生してしまいます。
(Wifi・socket接続している期間はAPからのデータが送信されてくるタイミングをはさんで十分とってあるつもりです)

ちなみに、Wifi・socketを接続した状態のまま、(Wifi・socket切断をしないで)APからのデータを受け取り続けると、データを取りこぼすことなく、すべて受信します。



Wifi・socket接続⇔Wifi・socket切断を行うと、Wifi機器から送られてくるデータを受け取らない状態が発生してしまう理由がわかりません。
Wifi・socket接続を切断するときには、InputStream,OutPutStream,soketをcloseしてから、wifiを切断しています。

個人的には受信の仕方に問題があるのかなと思っているのですが。
ご教授よろしくお願いします。


データの受信部分は以下のようなソースコードに記述してます。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(wifiの接続を行ったあとに)
      int size;
        final byte[] w = new byte[2000];
               :
               :
               :

    socket = new Socket(ip, port);

     in = socket.getInputStream();
            out = socket.getOutputStream();
               :
               :
               :

    // 受信ループ
            while (socket != null && socket.isConnected()) {

                size = in.read(w);
                if (size <= 0){
                    continue;
                }

    (*1)
                byte[] sdsd = new byte[size];

                for(int j=0;j<size;j++){
                    sdsd[j] = w[j];
                }
                String sasas  = new String(sdsd,"US-ASCII");

                Log.i("受信データ:",sasas);

            }

             :
             :
             :

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

だい

unread,
Feb 11, 2014, 5:00:19 AM2/11/14
to android-g...@googlegroups.com

すみません、だい@投稿者 です。

こちら的を得ていない質問内容になっているかもしれません。

Wifi機器との接続・切断動作を行うのにtimerを利用したServiceを起動して、定期的にBroadcastし、それをトリガーとして動作させているのですが、
もしかしたら、こいつが悪さしているのかもしれないです。。。 
(このServiceをbroadcastさせずにただカウンタ値をLogcat表示させる動作にして、裏で動かした状態で
、Wifi機器との接続を維持したまま動作をみていると、かなり遅れて(1分30秒とか・・)から size = in.read(w);の後段にすすんでいるのを確認しました。。)

ん~私としてはServiceは別プロセスでうごいているので、データ受信に対してはおおきく邪魔しないと思っているのですが・・・

というか、size = in.read(w); の後段にすすむ条件がよくわかってないです。詳しい方、よろしくお願いします。

さわださとし

unread,
Feb 11, 2014, 6:03:46 AM2/11/14
to android-g...@googlegroups.com
さわだです。

Androidに限らない一般論ですが。

送信側で出力ストリームにwrite()したあとにflush()を呼んで強制的に送信
させればいいんじゃないでしょうか?
出力ストリームのデータが少ない時は、適度なサイズになるまで待つので、
write()しただけでは送信しないのです。
そのために、read()で待たされているのだと思います。
--
さわださとし
http://www.satoshis.com/
Message has been deleted

だい

unread,
Feb 13, 2014, 6:54:31 AM2/13/14
to android-g...@googlegroups.com
さわだ さま

ご回答ありがとうございます。
いろいろこちらの問題で試行錯誤しております。
現在、Wifi機器にandroid端末とPCを同時に接続して実験してみました。

android端末、PCともに受信したらそのデータを表示するという状況にしております。
Wifi機器にandroid端末とPCを同時に接続し、接続を維持し、
Wifi機器からAP経由で同じデータを同じタイミングで送信してみますと、PCはすぐに(体感で1秒以内)受信しますが、
android端末は1~10秒以内、悪いときは1分以上たってからデータ表示される(Logcat表示)状況です。

送信側へのご指摘をいただきましたが、送信側は明らかに送信動作を
していると思うのです。

android端末でWifiで受信したデータがinputStreamに到達するのはどんなタイミングなのでしょうか?

また、ソースの受信部での

  size = in.read(w);

はin(InputStream)にデータが来れば、即時にreadされるものなのでしょうか?


2014年2月11日火曜日 20時03分46秒 UTC+9 Satoshi Sawada:

Shigeo Mutoh

unread,
Feb 13, 2014, 9:22:45 AM2/13/14
to android-g...@googlegroups.com
武藤です。

だいさんのソース見て、Javaのsocket listenのコードってあんなんじゃ
なかったよなあと思ってたのですが、正解はすぐには思いだせません
でした。

たぶんSocketの代わりにServerSocketを使うのが吉なんじゃないでしょか。
http://www.techscore.com/tech/Java/JavaSE/Network/3/
とか。

なぜ良いかはわかりませんねえ。うまくいったら教えてください。

では。


さわださとし

unread,
Feb 13, 2014, 9:14:47 PM2/13/14
to android-g...@googlegroups.com
さわだです。

Android用のパケットキャプチャアプリがあるようです。
https://play.google.com/store/apps/details?id=jp.co.taosoftware.android.packetcapture&hl=ja

これを使って実際のパケットのやりとりがどうなっているのか確認して
みると何かわかるかもしれません。
> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このグループから退会し、メールの受信を停止するには、android-group-j...@googlegroups.com
> にメールを送信します。
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> http://groups.google.com/group/android-group-japan からこのグループにアクセスしてください。
> その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。



--
さわださとし
http://www.satoshis.com/

だい

unread,
Feb 20, 2014, 6:00:31 AM2/20/14
to android-g...@googlegroups.com
武藤さん

ご回答ありがとうございます、android側ではAPにつなぎにいく(connect)クライアントとして動作を想定しておりますので、
ServerSocketの使用はきびしいかと理解しております。

さわださん

ご回答ありがとうございます、パケットのやりとりを見てみましたが解析がなかなかむずかしいです。。。


いろいろと試してみて感じているのは、そもそもandroid端末はデータをWifi通信で受信した後、すぐにアプリのInputstreamに反映されないときと、反映されるときが
あるような気がします。すぐにアプリのInputstreamに反映されるものなのでしょうか?
私の買ってな考えでは、wifiで受信したデータは一旦端末のBufferみたいなところに入って、その後、なんらかのイベントでInputStereamに入ってくる
と考えているのですが、そのあたりがどうも調べきれません。
wifiで受信したデータがアプリケーションレベルの操作ができるようになるまでには、どのようなことがおこっているのか、
詳しい方おられましたらどうぞよろしくお願いします。


2014年2月11日火曜日 17時17分11秒 UTC+9 だい:

田代透

unread,
Feb 20, 2014, 6:30:58 AM2/20/14
to android-g...@googlegroups.com
AndroidとかWifiの問題ではなく基礎的なJavaでの通信に関する知識不足なのではないでしょうか



2014年2月20日 20:00 だい <dadaik...@gmail.com>:

--
このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
このグループから退会し、メールの受信を停止するには、android-group-j...@googlegroups.com にメールを送信します。
このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
http://groups.google.com/group/android-group-japan からこのグループにアクセスしてください。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。



--
--
Toru Tashiro
toru...@gmail.com

だい

unread,
Mar 19, 2014, 10:14:07 AM3/19/14
to android-g...@googlegroups.com

Toruさん

ご回答ありがとうございます。
私のJavaにおける通信知識不足は承知の上、調べてもなかなか確信部分にたどりつけず、ご質問させていただいております。

自作Wifi機器からは50byteくらいのASCIIデータが送られており、それをsocket通信で受信しています。
Fileのデータのように改行がデータ末尾に含まれるデータではありません。なので、 .read(byte[])が有効なメソッドだと考えています。

さらに、自作Wifi機器とPCでWifi通信をさせて、Wiresharkで自作Wifi機器から送られてくるパケットを見てみたところ、ヘッダ部分のPSH=1になっており、パケットのコントロールフラグに関しては、問題ないと思われます。

なので、端末側のOSの問題なのか、もしくは私の自作アプリのデータ通信方法が間違っているのか、はたまたTCP通信というのはそういうもの(通信完了に秒オーダーの時間を有する場合がある)なのか、確信にたどりつけずにいます。。。50byte程度のデータ量でそんなに時間かかるのか?と思っているのですが、、、
お詳しい方、いらっしゃいましたらどうぞご教授よろしくお願いします。


2014年2月20日木曜日 20時30分58秒 UTC+9 Toru:
AndroidとかWifiの問題ではなく基礎的なJavaでの通信に関する知識不足なのではないでしょうか



このグループから退会し、メールの受信を停止するには、android-group-japan+unsubscribe@googlegroups.com にメールを送信します。
このグループに投稿するには、android-group-ja...@googlegroups.com にメールを送信してください。

http://groups.google.com/group/android-group-japan からこのグループにアクセスしてください。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。

Kyash

unread,
Mar 19, 2014, 7:53:30 PM3/19/14
to android-g...@googlegroups.com
Kyashと申します.
私も通信等にはあまり詳しくないですが,ちょっと気になったのでコメントします.
(内容は間違っているかもしれません...)

size = in.read(w)以降に進む条件ですが,(以降は私が持っているイメージです,嘘書いているかもしれません!)
linuxの通信バッファ内にデータが格納され,Androidがバッファを確認しにいき,そこにデータがあったらsizeが0より大きくなり,先に進むと思います.したがって,通信ループに入っても,Wi-Fi機器からデータがこなければ先に進まないかと...

あと,ちょっと気になっているのが,
> Serviceは別プロセスでうごいているので、データ受信に対してはおおきく邪魔しないと思っているのですが・・・
これは,Serviceをandroid:process="xxx"みたいな感じで,完全に独立したプロセスで動作させているという意味でよいのでしょうか?
Service自体は,基本的にはメインスレッドで動作するので,他のActivityなどがメインスレッド上で動作していると待たされる可能性はあります.
ただ,通信接続作業は別スレッド上で動作させてあると思いますので,そのスレッドがスタートしてしまえば関係ないのではないかと思いますが...

AndroidにもLinuxについてもあまり詳しくないのに,口を挟みました.
何かの参考になれば幸いです.
以上です.

2014年2月11日火曜日 19時00分19秒 UTC+9 だい:

hyouga00

unread,
Mar 26, 2014, 8:52:19 AM3/26/14
to android-g...@googlegroups.com
ひょうがと申します

wifi 切断 → wifi再接続 に時間がかかっているという事はないでしょうか?

ひとえにwifi切断、接続といっても、裏でいろいろうごきます。

再接続の際、APのスキャン、アソシエーション、など手続きがある上に、
wifi driver -> wpa_supplicant -> wifimonitor -> wifiservice など
かかわるコンポーネントも多いので。

説明を求められるかもしれませんが、なかなか深い世界なので、説明しきれません
ご了承くださいm(_ _)m

だい

unread,
Apr 23, 2014, 7:23:51 AM4/23/14
to android-g...@googlegroups.com
ひょうがさま

ご回答ありがとうございます、wifiの再接続は正常に行われた後、
通信動作(Wifi機器からデータ送信する)を行うようになっておりますので、接続が
遅いことは起因しないとおもっています。



>ひとえにwifi切断、接続といっても、裏でいろいろうごきます。

>再接続の際、APのスキャン、アソシエーション、など手続きがある上に、
>wifi driver -> wpa_supplicant -> wifimonitor -> wifiservice など
>かかわるコンポーネントも多いので。

そんな感じですよね・・・何が原因なのか・・

ちなみに 
wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF , "MyWifiLock");
wifiLock.acquire();

をソースに記述すると、実機の受信動作がなんだか調子よいんですが、
これって、WIfiの通信速度に関係するのでしょうか?


2014年3月26日水曜日 21時52分19秒 UTC+9 hyouga00:

だい

unread,
Apr 23, 2014, 7:27:08 AM4/23/14
to android-g...@googlegroups.com
Kyashさま

ご回答ありがとうございます。

>size = in.read(w)以降に進む条件
は私もこのような認識だったので、安心しました。

>これは,Serviceをandroid:process="
>xxx"みたいな感じで,完全に独立したプロセスで動作させているという意味

ご指摘ありがとうございます、実際には完全に独立したプロセスで動作させていませんでした。
ご指摘のとおり、完全別プロセスにしてみましたが、
受信動作に変化はありませんでした・・


2014年3月20日木曜日 8時53分30秒 UTC+9 Kyash:

だい

unread,
Jun 2, 2014, 8:18:06 PM6/2/14
to android-g...@googlegroups.com
ご回答者いただいた皆様

だいです。たくさんの方々、アドバイスありがとうございました。
android端末とWifi機器の無線のやり取りをパケットキャプチャしてみました。
すると、動作がどうもかみ合っておらず、端末側は電源管理がPowerSaveモード、Wifi機器側は常にActiveモードで動作して
いることに気がつきました。Wifi機器側の設定を見直してPSモードに対応する形でパラメータ設定しなおすことで
パケットのやりとりはプロトコルにもとづくやりとりになり、受信遅れ動作も解消された模様です。
androidのソースは原因はなかった模様です。
しかし、たくさんの方々からいただいたアドバイスから可能性をつぶしていき、
今回の結果に結びついたと思います。
ありがとうございました。


2014年2月11日火曜日 17時17分11秒 UTC+9 だい:
Reply all
Reply to author
Forward
0 new messages