1

サーバーからイベントを読み取るクライアント側ソケット ソフトウェアを作成しています。(たとえば、株価のストリーミング)。

問題: .read(b); -1の値ですぐに返されます。これにより無限ループが発生し、電話機が非常に熱くなります。さらに、s.isConnected()、isOpen()、isBound() に対するすべてのチェックは true を返します。基本的に、ソケットは接続されているように見えます。(これはエラー シナリオであるため、.setSoTimeout(x) の値は影響しません。12 分、または空のままにします。.read(b) は常にすぐに -1 を返します)。

後で getOutputStream() を介して書き込むと、例外 EPIPE (壊れたパイプ) を受け取ります。

コア コードは次のとおりです (簡潔にするために、ログ ステートメント/値チェックは省略されています)。

s.connect(new InetSocketAddress(host, port), CONNECT_TIMEOUT_MILLIS);

byte[] b = new byte[1024];
while (s.isConnected()) {
    int bytesToRead = s.getInputStream().read(b);
    if (bytesToRead <= 0) {
        LOGGER.debug("no bytes read? trying again.");
        continue;
    }
    processFrame(b);
}

電話で 3g を循環させると、正常に動作します。時々、この奇妙な状態に陥ります。

質問

私は何か間違ったことをしていますか?これは予想される動作ですか?Android でソケット プログラミングを行う正しい方法を示すために参照できる既存のコードはありますか?

4

3 に答える 3

3

次のコードを問題なく使用します。

        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line = null;
        while ((line = in.readLine()) != null) {
            myLineProcess(line); //here you process you line result
        }

幸運を。

于 2012-09-26T00:54:13.243 に答える
2

戻り値が0未満の場合read(byte[], ...)、ピアは接続を閉じているため、ソケットを閉じてループを終了する必要があります。これ以上のデータはありません。

入力ストリームがブロックされているため、read(byte[], ...)ゼロを返す唯一の方法は、呼び出すオーバーロードに応じて、長さゼロのバッファーまたは長さゼロを指定することです。あなたがそれをしていないので、それは決してゼロを返しません。

代わりに、Javadocに記載されているとおりに動作します。つまり、EOSを意味する-1を返すか、少なくとも1バイトのデータが使用可能になるまでブロックします。

私は何か間違ったことをしていますか?

ほとんど全部。のループテスト<= 0は完全に無意味であり、完全に正しくありません。そして、テストもそうですisConnected()。これは、これを接続したことがあるかどうかを示すだけですSocket。接続状態によって変化することはありません。戻りコード-1は、それを示しています。ループは次のようになります。

while ((bytesToRead = s.getInputStream().read(b)) > 0)
{
    // do something with b[0..bytesToRead -1].
}
s.close();
于 2012-09-26T02:01:17.083 に答える
0

これがこれに対する適切な答えであるかどうかはわかりませんが、それでもコードを提供したいと思います。これは毎回うまく機能します。

シンプルにしてください、

使ってみてInputStream, InputStreamReader, BufferedReader, OutputStream, PrintWriter.

クライアント側:

Socket s = new Socket();
s.connect(new InetSocketAddress("Server_IP",Port_no),TimeOut); 
// Let Timeout be 5000

サーバ側:

ServerSocket ss = new ServerSocket(Port_no);
Socket incoming = ss.accept();

ソケットから読み取る場合:

InputStream is = s.getInputStream();
InputStreamReader isr = new InputStreamReader(is);

BufferedReader br = new BufferedReader(isr);
boolean isDone = false;

String s = new String();

while(!isDone && ((s=br.readLine())!=null)){

     System.out.println(s);   // Printing on Console

 }

ソケットへの書き込みの場合:

OutputStream os = s.getOuptStream();
PrintWriter pw = new PrintWriter(os)

pw.println("Hello");
于 2012-09-26T05:37:37.710 に答える