アプリ版:「スタンプのみでお礼する」機能のリリースについて

お世話になります、androidでsocket通信を行なうプログラム(Wifi経由)を作成しておりますが、周期的に何度も接続、通信、切断をくりかえしておりますと、ソケットの.connectをするところで以下のエラーが出ます。

java.net.ConnectException: failed to connect to /192.168.10.12 (port 50000): connect failed: ENOBUFS (No buffer space available)

周期動作としては、
ソケットの接続後、受信待ち状態はスレッド内でソケットのInputStreamの.read()で行い(読み取ることができるまでブロックされるメソッド)、送信は、別のスレッドを起こしてソケットのOutputStreamでのflush()で送信しています。ある周期的タイミングで切断の手順を踏みます。

エラーの内容からして、切断するメソッド発行時にちゃんとリソースが解放されていない?のではないかと考えます。今、私がソケットを閉じよとする際に発行しているメソッドは以下になります(順同)
(1)ソケットのOutputStream.close
(2)ソケットのInputStream.close
(3)ソケット.close


正常にソケット回りのリソースを解放する手順としてソケットの閉じる方法は間違っていますでしょうか?
ちなみに、このエラーが出た後はインターネットへの接続も不可状態になり、端末を再起動しないと復帰しません。
大変困っております、お詳しい方おられましたら、よろしくお願いします。

A 回答 (3件)

No.1です。



connectエラー発生時にTIME_WAIT状態のものがないことが確認できたのだったら、
この件とは別の問題なのだと思いますが、この質問をするなら、どれくらいの時間間隔で
繰り返しているかだけでなく、エラーが発生するのがどれくらいの回数を繰り返して
なのか、あるいはどれくらいの時間を繰り返してなのかもちゃんと書いた方がよいと
思います。
1分間隔でconnectしているのだとしたら、1時間繰り返しても60コネクション程度
なので、もし1時間程度で発生するのだったら、メモリ不足になるほどメモリを
消費しているという可能性は低いかもしれません。もちろん1コネクション生成に
あたってアプリが膨大なメモリを使っていて、それがうまく解放されてないのでしたら
メモリ不足になる場合もあると思います。そうであればメモリ使用量を監視すれば
なにかわかると思います。

また、繰り返し周期を2倍遅くしたら、エラーが発生し始める時間も2倍遅くなるのか、
それとも回数に依らず一定時間でエラーが発生し始めるのかを試してみると、
エラー発生要因を探る手がかりになると思います。

あと、ソケット切断後にwifiを切断しているというのも何のためにどのようにしている
のかよくわかりませんでした。
これってwifiの設定をあなたのアプリが勝手にOFFにするということなのでしょうか?
なぜアプリが勝手にwifiの設定をOFFにするのかよくわからなかったので、じゃあwifiを
切断しなかったらどうなるのかというのも試してみた方がよいと思いました。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。いろいろやってみましたが、瞑想しています。。エラーが起こるのは、1分間隔で1000~2000回動作させた場合に起こることが多いです、が、イメージとしては毎回同じタイミングで出ているという感覚ではないです。WifiのOFF/ON(Wifimanager#enabled(true/false))はシステムの都合上、3G回線につないで、インターネットに接続するためです。ソケット接続は自作wifi機器のAPに対して行いますが、そのAPの先にはインターネットはいないため、このような動作をさせています。なので、実際にはwifiON→APに接続→ソケット接続→ソケットで通信→ソケット切断→WifiOFFを繰り返しています。また、ご指摘いただいたようにWifiをつないだままの状態で、ソケット接続・通信・切断をくりかえしてみましたところ、5000回以上エラーはでませんでした。

お礼日時:2015/01/28 20:18

お役に立てるかどうか分かりませんが、



RFC5802 で、

For the SCRAM-SHA-1/SCRAM-SHA-1-PLUS SASL mechanism, servers
SHOULD announce a hash iteration-count of at least 4096. Note
that a client implementation MAY cache ClientKey&ServerKey (or
just SaltedPassword) for later reauthentication to the same
service, as it is likely that the server is going to advertise
the same salt value upon reauthentication. This might be
useful for mobile clients where CPU usage is a concern.

と書いてあるのを、見つけました。
    • good
    • 0

TCP/IPプロトコルでは、切断を開始した側は切断手順の最後に必ず


タイムアウト待ち(TIME_WAIT状態)になることをご存知ですか?
http://www.atmarkit.co.jp/ait/articles/0402/13/n …
の「TCPの状態遷移図」を参照してください。

これは、OutputStreamだけを先に閉じるハーフ・クローズ手順でも同じです。
http://www.geocities.jp/taka_owl2005/job/UNIX/ne …
も参考にしてください。

このTIME_WAIT時間はシステムによってデフォルト値が異なりますが、
Windowsで240秒、CentOSで60秒です。Androidがどうなっているか知りませんが
おそらくLinux系で60秒くらいだと思います。
コネクションの接続/切断周期がこれより短いのであれば、TIME_WAIT状態の
コネクションがどんどん増えて行き、確実にリソース不足になります。

このTIME_WAIT時間の設定を自分の接続/切断周期以下にすればリソース不足は
解消されると思いますが、この値はネットワーク状態に応じて決めるべきもの
であり、アプリの都合で変えるべきものではありません。
根本的には、頻繁な接続/切断の繰り返しを避けるよう設計する必要があります。

この回答への補足

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

私のほうでもTIME_WAITについて疑ってみましたが、おっしゃるとおりandroidのタイムウエイトは60秒であるようでした。(実際にnetstatというアプリで監視してみますと、TIME_WAIT状態になったものは60秒後に消えました)

私の作っているシステムは60秒周期で1つのソケットをandroid端末側から接続して、双方通信して、android端末側から切断するという動作を行なっております。ちなみにWifiの通信の切断も
ソケット切断の3秒後に実施しています。

60秒周期で動作を繰り返しておりますので、TIME_WAIT状態のものがたくさん生成されている状態は考えにくい+実際にENOBUFSが起こっている状態でnetstatアプリで確認したところ、TIME_WAITがたくさんある状態ではありません(むしろLISTENなプロセスが1つあるだけ、のような状態です)

他に疑わしい事柄はありますでしょうか?

ソケットプロセスがTIME_WAITにある状態でWifiを切断するのがまずい?とかあるのでしょうか・・・。

補足日時:2015/01/22 16:30
    • good
    • 0
この回答へのお礼

>No.1様 またがってすみません。wifiを切断しなければ問題なく動作しました。wifiのON/OFFのみを十分に繰り返したのち、ソケット接続を実施しますと問題なく接続できました。具体的な実装に問題があるのでしょうか?wifiは毎回接続したいSSIDの接続履歴を削除し,WifiConfigrationで新たにnetidを取得して接続します。socketはsocket.connect(,)で接続した後、InputStream(inとします)・OutputStream(outとします)を取得し、in.read(byte[])を∞ループで実施し、受信状態を常に保ちます。outはout.wite,out.flushで送信します。通信データは10byte程度です。そして、ある周期タイミングが来た時点で out.close in.close socket.close の順にクローズしていきます。

お礼日時:2015/01/28 20:33

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!