【发布时间】:2018-03-22 10:58:11
【问题描述】:
基本上,我想要实现的是完成客户端套接字和服务器套接字之间的乒乓通信。
场景应该是这样的:
- 客户端建立与服务器的连接。
- 客户端发送“Hello”到服务器(通过OutputStream),然后开始从服务器读取(通过InputStream)
- 服务器读取“Hello”消息并打印到控制台,然后将“Hello”发送到客户端(通过 OutputSteam)。
- 客户端打印来自服务器的响应消息并退出。
服务器套接字:
try (ServerSocket serverSocket = new ServerSocket(8080)) {
while (true) {
// Blocking here
Socket socket = serverSocket.accept();
InputStream inStream = socket.getInputStream();
OutputStream outStream = socket.getOutputStream();
String reqMessage = new String(inStream.readAllBytes(), StandardCharsets.UTF_8);
System.out.println(reqMessage);
String resMessage = "Hello";
outStream.write(resMessage.getBytes(StandardCharsets.UTF_8));
outStream.flush();
System.out.println(String.format("Message '%s' has been sent to client", resMessage));
outStream.close();
socket.close();
}
}
客户端套接字:
Socket socket = new Socket("localhost", 8080);
OutputStream outStream = socket.getOutputStream();
outStream.write("Hello Server".getBytes(StandardCharsets.UTF_8));
outStream.flush();
InputStream inStream = socket.getInputStream();
System.out.println("Received from server");
System.out.println(new String(inStream.readAllBytes(), StandardCharsets.UTF_8));
outStream.close();
socket.close();
我的问题:
一旦建立连接,双方都被阻塞,没有人打印正确的消息,就像他们在等待对方一样。一旦我关闭客户端,服务器就会打印所有正确的信息。但是,如果我从客户端删除了“从服务器读取”部分,即 InputStream 部分,那么双方都可以正常工作。我只是感到困惑,为什么它会这样?如果我想让它工作,我应该修改什么?
谢谢。
【问题讨论】:
-
你研究过NIO非阻塞socketstackoverflow.com/questions/11745686/java-nio-client/…
-
您的问题是什么,您是否尝试在服务器中第二次调用
inStream.readAllBytes()以确保返回一个空数组(= 流标记结束)。如果在客户端关闭套接字之前从未调用过第二次调用,则在网络套接字流中无法识别 EOF 对这个函数有用。您可以定义消息格式numOfBytes(64bit),databytes并在您的服务器和客户端中相应地读取。不要等待真正的文件结束/流结束状态。 -
@Whome 是的,但我只是在热身并练习一些基本概念,我认为 Kayaman 给出了正确答案,所有问题都来自
readAllBytes(),它一直等到流关闭,这将永远不会发生。