- PR -

InputStream#available()について

1
投稿者投稿内容
84
ベテラン
会議室デビュー日: 2005/11/04
投稿数: 83
投稿日時: 2008-10-01 22:42
いつもお世話になっております。

Socket#getInputStream()から取得できる
InputStreamのavailableメソッドについて質問です。

まず、質問の前提として、
クライアント-サーバ間でデータを送受信する構成になっています。
サーバは単純にServerSocketでクライアントを待ち受けて、
accept()でSocketを取得し、SocketからInputStreamを取得します。
続いて、InputStreamからデータを読み込む、という処理になっています。

このとき、
クライアントがデータを送信しているにも関わらず
サーバがread()で 0[byte]しか読めないことがあるので、
read()の前に、available()が"0"かどうかチェックして
"0"であれば、数100[msec]のスリープ後に
再度read()することで正常に読めるケースがあります。

ここで質問なのですが、

1)クライアントがデータを送信しているにも関わらず、
available()で"0"が返ってくる、
というのは具体的にどういう状況のときなのでしょうか。

2)クライアント側のソースに修正を加えることで、
最初のavailable()が"0"となるように細工することは可能でしょうか。

3)N/Wのトラフィックや構成機器の状況にもよると思っているのですが、
この現象が起こりやすい or 確実に起こせるような状況を
つくることはできるでしょうか。

ご存知の方いらっしゃいましたら、
教えていただけるとさいわいです。

よろしくお願いします。
スフレ
ぬし
会議室デビュー日: 2005/05/27
投稿数: 281
お住まい・勤務地: 東京
投稿日時: 2008-10-02 01:47
1)クライアントが送ったデータがサーバに到達していない状況
2)できません。
3)クライアントで、ソケットをconnect()してからデータを送らなければ再現できると思います。

経験上、available()を使うプログラムは実装か設計が間違っています。通常はavailable()を使う必要はありません。たとえば、「サーバはまず最初にクライアントから4バイト受け取る」というプロトコルだったら、
コード:
DataInputStream dis = new DataInputStream(soc.getInputStream());
byte[] data = new byte[4];
dis.readFully(data);


で良いのです。接続が切れるなど異常があれば例外が出ます。

ranco
大ベテラン
会議室デビュー日: 2007/11/02
投稿数: 112
投稿日時: 2008-10-02 08:56
> available()を使うプログラムは実装か設計が間違っています。通常はavailable()を使う必要はありません。
非常に正しいと思います。たぶんOPはSocket I/Oの標準的な書き方をしていないのだと思います。
84
ベテラン
会議室デビュー日: 2005/11/04
投稿数: 83
投稿日時: 2008-10-04 01:25
スフレさん、rancoさん

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

availableは確かに必要ないですね。
よくよく考えてみたのですが、いくつか勘違いしていたようです。

>サーバがread()で 0[byte]しか読めないことがあるので、
InputStreamのソースを見る限り
これはまずありえないですね。

いろいろとアドバイスいただき、
間違いに気づくよいきっかけになりました。

ありがとうございます。
1

スキルアップ/キャリアアップ(JOB@IT)