sokcetのエラー

2,016 views
Skip to first unread message

もばたろう

unread,
Jan 10, 2015, 3:39:47 AM1/10/15
to android-g...@googlegroups.com
お世話になります、socket通信のエラーについて質問です。
socket.connect でsocket接続をするプログラム何度も接続→通信→切断(.close)を繰り返して
いると、以下のエラー(ENOBUFS )がスローされます。


01-09 09:06:46.418: W/System.err(29936): java.net.ConnectException: failed to connect to /192.168.10.12 (port 50000): connect failed: ENOBUFS (No buffer space available)
01-09 09:06:46.418: W/System.err(29936):     at libcore.io.IoBridge.connect(IoBridge.java:114)
01-09 09:06:46.418: W/System.err(29936):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
01-09 09:06:46.418: W/System.err(29936):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:460)
01-09 09:06:46.418: W/System.err(29936):     at java.net.Socket.connect(Socket.java:838)
01-09 09:06:46.418: W/System.err(29936):     at java.net.Socket.connect(Socket.java:791)
01-09 09:06:46.418: W/System.err(29936):     at com.example.simple_test.Wifi_Service.Socket_Connect(Wifi_Service.java:2033)
01-09 09:06:46.428: W/System.err(29936):     at com.example.simple_test.Wifi_Service$10.run(Wifi_Service.java:1938)
01-09 09:06:46.428: W/System.err(29936): Caused by: libcore.io.ErrnoException: connect failed: ENOBUFS (No buffer space available)
01-09 09:06:46.428: W/System.err(29936):     at libcore.io.Posix.connect(Native Method)
01-09 09:06:46.428: W/System.err(29936):     at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85)
01-09 09:06:46.428: W/System.err(29936):     at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
01-09 09:06:46.428: W/System.err(29936):     at libcore.io.IoBridge.connect(IoBridge.java:112)
01-09 09:06:46.428: W/System.err(29936):     ... 6 more


このエラーの直接的な発生理由がわかりません。
お詳しい方おられましたらご教示よろしくお願いします。

Shigeo Mutoh

unread,
Jan 10, 2015, 9:49:59 AM1/10/15
to android-g...@googlegroups.com
武藤です。

ENOBUFSというのはlinuxのOSレベルでのエラーコードを示しており、
エラーメッセージに書いてあるとおりバッファがいっぱいだと言ってます。

なので非常に頻繁に通信しようと試みたか、そもそも送信するデータ量が
多すぎるかのどちらかで発生すると予想できるわけですが、単に何度か
接続と切断をしただけで発生するするのであれば、OSのバグではなかろうか
と考えるしかありません。

しかし、おそらくそれはないと思うので、通信の頻度や通信量について
今一度確かめてみてはいかがでしょうか。

では。

もばたろう

unread,
Feb 4, 2015, 6:09:59 AM2/4/15
to android-g...@googlegroups.com
武藤さま

ご返答ありがとうございます、いただいたアドバイスからいろいろやってみたのですが、
確信にたどり着けません。。。
通信頻度ですが、1分間隔で動作させており、1回の通信でのデータは(送信・受信ともに)15バイト程度です。
また、システムの都合上、Wifiを自作APに接続して、ソケット接続・通信・切断をおこなったのち、WifiをOFFにしてモバイル回線での通信に切り替えることを
おこないます。これを周期動作させております。
また、wifiを接続したまま、ソケットの接続・通信・切断を繰り返しても、ENOBUFSエラーは起こりません。(エラーが起こりえるだろう十分な回数・時間を動作させました)

ソケットのTIME_WAITが残っているかを疑いましたが、TIME_WAIT状態になると約60s後にプロセスは消えていますので、問題なさそうです。

長期動作させているうちに通信まわり以外の部分でメモリを食ってるのかと疑い、EClipseでヒープの状態を監視してみましたが、得に増えていっている状態はみられませんでした。

また、このエラーが起こる端末と起こらない端末が存在するように感じています。。起こる端末の倍以上の回数・時間を動作させても、起こらない端末では起こりませんでした。
(もしかすると、それだけ動作させてもKernelレベルのバッファにまだ余裕があったとか?)

実際にlinuxOSレベルのバッファの状態を確認しながら、どのタイミングで増えるのかを確認しながらENOBUFSの発生要因を追いたいと思っておりますが、そういった方法はありますでしょうか?

アプリとかで監視できるものはあるのでしょうか? 重ね重ねすみませんがよろしくお願いします。

Shigeo Mutoh

unread,
Feb 4, 2015, 10:59:07 PM2/4/15
to android-g...@googlegroups.com
武藤です。

たぶんENOBUFSの発生原因を容易に特定するのは簡単ではないとももいます。
なぜならerrnoはグローバルに一つではなく、スレッドごとに存在するからです。
(ようするに、システムには山のようにerrnoがある)

あまり参考にならないと思いますが、「私だったらこうする」というふうに
書いてみます。

まず、問題のjavaの箇所を特定する。
https://android.googlesource.com/platform/libcore/+/15a93894f19b27f3d85b8e3c3de8cff8a33964d3/luni/src/main/java/libcore/io/Posix.java

なるほどそうですかと。Posix, connectに入ってくのね。
これかあ。
http://osxr.org/android/source/libcore/luni/src/main/native/libcore_io_Posix.cpp#0435

どいつがthrowしてんだ?
このマクロ??
NET_FAILURE_RETRY

このへんで追うのやめ。
どうするか悩む。
とりあえずnative code書いて同じことやってみるばもう少し発生原因を
突き止められるハズ...。

てな感じですが、本当に適当ですみません。

では。

Shigeo Mutoh

unread,
Feb 5, 2015, 3:06:01 AM2/5/15
to android-g...@googlegroups.com
武藤です。

もしかしてudpですか?
だったらDatagramSocketを使えってオチなのかも。

tcpだっとして、ダメなときは初回からダメですか?
もし繰り返していくうちにダメになるなら、Socketインスタンスを
使いまわしていることが障害かも知れません。
closeしたらもうそのインスタンスを捨てて、通信の度にnewしなおして
みてはどうでしょう?

では。

もばたろう

unread,
Feb 5, 2015, 3:50:13 AM2/5/15
to android-g...@googlegroups.com
武藤さま

ご見解をたくさんいただいてありがとうございます。
>もしかしてudpですか?
>だったらDatagramSocketを使えってオチなのかも。

tcpプロトコルでの動作になります。
Sokcet#connect(IP,PORT);のメソッド実行時にENOBUFSが発生します。

>tcpだっとして、ダメなときは初回からダメですか?

繰り返していくうちに発生します。
ただし、毎回同じ回数程度で発生するわけではないです。少なくとも1500回以上くらい動作させたら発生する端末では発生します。
5000回以上動作させても発生しない端末では発生しません。

>もし繰り返していくうちにダメになるなら、
>Socketインスタンスを 使いまわしていることが障害かも知れません。
>closeしたらもうそのインスタンスを捨てて、通信の度にnewしなおしてみてはどうでしょう?

Socketの変数宣言はメンバ変数で定義しております(Socket  sock ;)が、
インスタンス自体はメインではない別スレッド内でnewしております(sock  = new Socket() ;  ) 。
このスレッドを毎回の接続時に走らせておりますので、通信の度にnewしていることになっております。。

ご見解ありがとうございます。

2015年2月5日木曜日 17時06分01秒 UTC+9 TM:
Reply all
Reply to author
Forward
0 new messages