我正在尝试修复java套接字通信错误,其中服务器不知道输入消息长度。在当前情况下服务器测试,如果输入使用inputStream.available();
方法完成。但是,此方法始终不会返回正确的答案。它会导致读取部分输入。似乎有两种不同的可能性来解决这个问题。
客户端应发送输入大小。
客户端应在发送后关闭其输出流,但它会导致客户端无法读取响应,因为当输出流关闭时套接字也会关闭。
还有其他建议吗,特别是在nio包的帮助下?
谢谢。
答案 0 :(得分:1)
您可以使用
socket.shutdownOutput();
关闭客户端的输出流。这将显示为关闭的输入流而不关闭套接字。
BTW:尽管你可以,但你不能使用socket.getOuputStream().close();
。
IMHO发送长度是最佳选择,因为这将允许您使用相同的套接字发送多个请求。
这是一个例子
public class SimpleServerMain {
public static void main(String... args) throws IOException, InterruptedException {
ServerSocket ss = new ServerSocket(54321);
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
for (String line; (line = br.readLine()) != null; )
System.out.println("Got " + line);
PrintStream ps = new PrintStream(s.getOutputStream());
for (String word : "Hello World Bye Bye!".split(" ")) {
ps.println(word);
Thread.sleep(1000);
}
s.close();
ss.close();
}
}
和
public class SimpleClientMain {
public static void main(String... args) throws IOException {
Socket s = new Socket("localhost", 54321);
InputStream inputStream = s.getInputStream();
s.getOutputStream().write("Hello\n".getBytes());
s.shutdownOutput();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
for (String line; (line = br.readLine()) != null; )
System.out.println("Got " + line);
System.out.println("Disconnected.");
s.close();
}
}
答案 1 :(得分:1)
available()
不是消息长度的衡量标准,因此如果您对“正确答案”的定义是“消息长度”,则没有理由返回“正确答案”。
如果你想要一个消息长度,你必须发送一个。或者使用行或XML,序列化等自描述协议
答案 2 :(得分:0)
您只需要将消息拆分为您选择的大小的部分 收到新消息时,您只需检查该ID是否与上一个相同。如果是,则将新消息附加到第一个消息的末尾。如果不是,您可以使用上一条消息执行您想要的操作,并开始录制新消息 每次发送消息的所有部分时,客户端只会发送一条特殊消息说明已完成。
答案 3 :(得分:0)
至少还有两种未提及的方法可能应该是。
使用特殊字符表示某个输入的结尾。如果输入中不允许有新行,则\r\n
是一个选择。
使用某种序列化 - 您可以将数据作为JSON对象或XML左右发送,然后您就会知道何时没有更多数据。