こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

androidのSocketでの正常なリソース解放

お世話になります、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


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

投稿日時 - 2015-01-21 12:36:59

QNo.8898916

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

14人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

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

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.

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

投稿日時 - 2015-01-23 11:49:44

ANo.2

No.1です。

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

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

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

投稿日時 - 2015-01-22 22:48:43

ANo.1

TCP/IPプロトコルでは、切断を開始した側は切断手順の最後に必ず
タイムアウト待ち(TIME_WAIT状態)になることをご存知ですか?
http://www.atmarkit.co.jp/ait/articles/0402/13/news096_3.html
の「TCPの状態遷移図」を参照してください。

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

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

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

投稿日時 - 2015-01-22 10:30:14

補足

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

私のほうでも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:13

あなたにオススメの質問