我已经像这样声明了socket:
serverAddr = InetAddress.getByName(this.ip);
socket = new Socket(serverAddr, port);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);然而,下面的方法不起作用。in.ready()总是返回false,如果删除,程序将在String message = in.readLine();处冻结
private void receive() {
try {
InputStreamReader isr = new InputStreamReader(socket.getInputStream());
System.out.println(isr.getEncoding());
BufferedReader in = new BufferedReader(isr);
if (in.ready()) {
String message = in.readLine();
if (message != null) {
if (listener != null) {
listener.receiveMessage(ip, message);
} else {
print("Client recieved: " + message);//
}
}
}
in.close();
} catch (Exception e) {
print("Error with input stream: " + e);
disconnect();
}
}我该怎么解决这个问题呢?
编辑:
下面是在我的服务器类中发送消息的方式: out.println( message );out.flush();每当我在message中放入一些东西时,这都会在一个循环中发生。out在此循环后关闭。
发布于 2011-05-19 19:09:21
我脑海中浮现出三件事:
receive调用中都会重新打开输入流,并将其包装到BufferedReader中。这可能会将多个行读取到缓冲区中,并且在完成(关闭它)之后,剩余的缓冲字节将不再可用于后续的receive调用flush()和close()调用,但另一端并未接收到所有数据。也许在你的情况下这也是一个问题编辑:
简单地将in引用保留在receive方法之外不会完全解决您的问题。您应该使用while循环来读取所有缓冲的消息,并为每个人调用侦听器,例如:
if (in.ready()) {
String message;
while ((message = in.readLine()) != null) {
// ...
}
}但要小心,因为最后一行可能是部分读取的消息(例如,缓冲了3和1/2消息)。如果这是一个问题,您可以逐个读取消息以确定行何时结束,并使用PushbackReader来放回不完整的消息。
发布于 2011-05-19 18:58:50
你不应该像这样使用ready()。javadoc这样说:
“返回:如果下一次read()保证不阻塞输入,则返回True,否则返回false。请注意,返回false并不保证下一次read将阻塞。”
您的代码隐含地假设ready() -> false意味着下一个read将阻塞。实际上,这意味着下一个read可能会阻塞,也可能不会阻塞。
正如@EJP所说...只需执行read调用。
我能做些什么来防止阻塞呢?如果被阻止,客户端将无法发送任何内容
如果读操作中的阻塞对您的应用程序是一个问题,请使用单独的线程进行读取,或者更改您的代码以使用NIO通道选择器。
发布于 2011-05-19 18:45:00
只需删除in.ready()测试。这对你没有帮助。readLine()将被阻塞,直到有数据可用。如果还没有数据到达,您还计划做什么?
https://stackoverflow.com/questions/6057399
复制相似问题