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

如果read(byte[], ...)返回 < 0,则对端已关闭连接,因此您必须关闭套接字并退出循环。永远不会有更多的数据。

输入流是阻塞的,因此返回零的唯一方法read(byte[], ...)是指定零长度缓冲区或零长度,具体取决于您调用的重载。因为你不这样做,它永远不会返回零。

相反,它将完全按照 Javadoc 中所说的那样:要么返回 -1 表示 EOS,要么阻塞直到至少有一个字节的数据可用。

难道我做错了什么?

几乎所有的。您的循环测试<= 0完全没有意义而且完全不正确。测试也是如此isConnected()。这只会告诉您是否曾经连接过 this 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 回答