【发布时间】:2020-01-17 17:17:41
【问题描述】:
我的测试失败了,因为从 InputStreamReader 读取字节会进入无限循环。
@Test
public void testSingleRequest() throws IOException {
Server server = new Server(9000, 100);
new Thread(server).start();
Socket clientSocket = new Socket("localhost", 9000);
OutputStream out = clientSocket.getOutputStream();
InputStream in = clientSocket.getInputStream();
String payload = "a";
byte[] load = buildPushPayload(payload);
out.write(load);
byte[] response = IOUtils.toByteArray(in);
server.stop();
assertEquals(0, response[0]);
}
这是写入 InputStream 的代码
byte[] resp = buildPushResponse();
output.write(resp);
private byte[] buildPushResponse() throws UnsupportedEncodingException {
ByteBuffer buffer = ByteBuffer.allocate(1);
buffer.order(ByteOrder.BIG_ENDIAN);
buffer.putInt(0);
return buffer.array();
}
服务端和客户端都写入clientSocket输入输出流。 我似乎无法理解为什么会出现无限循环?
【问题讨论】:
-
我认为“无限循环”是错误的术语。我认为 testSingleRequest 在
IOUtils.toByteArray(in)上是 blocking - 您要求将整个流转换为字节数组。所以, toByteArray 一直在等待,直到输入流为 EOF。您还没有告诉它要读取多少字节,并且套接字仍然打开。相反,您可能想要检查 in.available(),并读取那么多字节。如果您正在寻找基于消息的套接字,您可能想尝试 websockets。 -
@Jamie 我是新手,你能帮我这里的代码吗?你是在建议
while(in.available()){ byte[] response = IOUtils.toByteArray(in);} -
我还应该关闭服务器输出流以使输入流对客户端不可用吗?
-
这里没有
InputStreamReader。或者任何无限循环。您不会将字节写入InputStream,也不会从Reader读取字节:您读取字符;而且这个协议不包含字符,它包含二进制数据。当您使用错误的术语并做出虚假声明时,即使不是不可能,也很难理解您在说什么。你应该使用DataInputStream。是的,您应该关闭发送方的输出流,否则您将永远不会在接收方收到 EOS。 -
但是你可以扔掉所有这些代码并分别使用
new DataOutputStream(socket.getOutputStream()).writeInt(0)和int resp = new DataInputStream(socket.getInputStream().readInt()。
标签: java sockets inputstream outputstream