Android套接字输入流读取(后跟EPIPE)

时间:2012-09-25 23:48:07

标签: java android sockets

我正在创建一些客户端套接字软件来从服务器读取事件。 (例如,流媒体股票报价)。

问题: .read(b);正在返回立即,其值为 -1 。这导致infinte循环,手机变得非常热。此外,对s.isConnected(),isOpen(),isBound()的所有检查都返回true。本质上,socket 看起来已连接。 (这是一个错误场景,所以.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上进行套接字编程?

3 个答案:

答案 0 :(得分:2)

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

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

相反,它将完全按照它在Javadoc中的说法执行:返回-1表示EOS,或阻塞直到至少有一个字节的数据可用。

  

我做错了吗?

几乎所有事情。您对<= 0的循环测试完全没有意义且完全不正确。测试isConnected()也是如此。这只会告诉您是否曾连接此Socket。它不会随着连接状态而改变。返回代码-1告诉你。你的循环应该是:

while ((bytesToRead = s.getInputStream().read(b)) > 0)
{
    // do something with b[0..bytesToRead -1].
}
s.close();

答案 1 :(得分:1)

我没有问题地使用以下代码:

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

答案 2 :(得分: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");