我正在创建一些客户端套接字软件来从服务器读取事件。 (例如,流媒体股票报价)。
问题: .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上进行套接字编程?
答案 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");