首先,请允许我向您展示我的客户端代码:
String command;
socket.setSoTimeout(5000);
while(true) {
try {
final byte[] targetArray = new byte[is.available()];
final int x = is.read(targetArray);
if (x == -1) {
System.out.println("end");
break;
}
if (x == 0) continue;
command = new String(targetArray);
handleCommand(command).start();
}catch (Exception e){
e.printStackTrace();
}
}
一旦连接到实际的套接字,客户端发送出一些身份验证数据,但不接收任何数据,现在,它等待从服务器接收数据,当它这样做时,它处理它很好等,除了,当我停止服务器(字面上关闭程序),什么都没有发生,而在现实中,我期望它发送EOF(-1)。相反,它只是始终输出0。
根据available
方法的文档(重点是我的):
返回估计值可以读取的字节数
和
使用这个方法的返回值来分配一个用来保存流中所有数据的缓冲区是永远不正确的…
所以根据你发布的最小代码,你不应该使用available
来分配缓冲区,因为它可能总是返回0
,这反过来又使read
操作总是返回0
。但是根据你的问题,你只有在发送程序关闭时才会看到这种行为,这应该意味着:
available
方法正确返回流中缓冲的字节数,因此这就是您接收数据的原因。即使你消耗接收到的数据比发送端发送的更快(所以一些零可能会出现在available
中),你只需要continue
而从不处理这种情况,这使得将来有一些其他循环来捕获(最终)接收到的非零长度数据。- 一旦发送端关闭,将有一个点,之后它将始终返回
0
,因为它没有数据。所以你分配零长度缓冲区,read
方法首先检查你的缓冲区是零长度,而不是EOF。
所以确保分配的缓冲区的大小至少是1
。
同时,根据Socket#getInputStream
方法的文档:
如果套接字上没有缓冲的字节,并且套接字没有使用
close
关闭,则available
将返回0。