linux上的Java套接字错误(发送0xFF,-3接收)
在使用Java开发WebSocket服务器时,我遇到了这个奇怪的错误。我把它简化为两个小java文件,一个是服务器,另一个是客户端。客户端只需发送linux上的Java套接字错误(发送0xFF,-3接收),java,linux,sockets,Java,Linux,Sockets,在使用Java开发WebSocket服务器时,我遇到了这个奇怪的错误。我把它简化为两个小java文件,一个是服务器,另一个是客户端。客户端只需发送0x00、字符串Hello,然后发送0xFF(根据WebSocket规范) 在我的windows计算机上,服务器打印以下内容: Listening byte: 0 72 101 108 108 111 recieved: 'Hello' 在我的unix设备上,相同的代码打印以下内容: Listening byte: 0 72 101 108 108
0x00
、字符串Hello
,然后发送0xFF
(根据WebSocket规范)
在我的windows计算机上,服务器打印以下内容:
Listening
byte: 0
72 101 108 108 111 recieved: 'Hello'
在我的unix设备上,相同的代码打印以下内容:
Listening
byte: 0
72 101 108 108 111 -3
它不会接收0xFF,而是得到-3,不会中断循环,也不会打印它接收到的内容
代码的重要部分如下所示:
byte b = (byte)in.read();
System.out.println("byte: "+b);
StringBuilder input = new StringBuilder();
b = (byte)in.read();
while((b & 0xFF) != 0xFF){
input.append((char)b);
System.out.print(b+" ");
b = (byte)in.read();
}
inputLine = input.toString();
System.out.println("recieved: '" + inputLine+"'");
if(inputLine.equals("bye")){
break;
}
我还将这两个文件上载到我的服务器:
当b是int时,它的行为仍然很奇怪。我发送0xFF(255),但收到65533(不是65535或255) 问题不在您显示的代码中。在这里:
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
您正在处理二进制数据,因此应该使用原始流-不要将其转换为用于读取字符的读取器
您收到的是65533,因为当一个值不能表示为真正的Unicode字符时,“Unicode替换字符”使用的是该整数。当前代码的确切行为将取决于系统上的默认字符编码,这同样不是您应该依赖的
此外,您假设每个字节都应转换为单个字符—实际上您假设的是ISO-8859-1。我还没有检查规格,但我怀疑这是你应该使用的
最后,您没有检查b
是否为-1-用于指示客户端已关闭流。值为-3的字节的位模式为111111 01。
值为-3的in具有11111111111111101的位模式
因此,您得到的值基本相同。我希望我能理解你为什么得到-3。而且你的EOS检查不正确。您应该读入一个int并将其与-1进行比较。如果为true,则表示您已到达流的末尾,因此请关闭套接字,或者更可能是关闭输出流,并相应地继续。否则将其转换为一个字节。目前您无法传输0xff,因为它将被视为与EOS相同。与上述Jon的解决方案不同,只需将字符集定义为ISO-8859-1即可。默认情况下,Java使用UTF-8
in = new BufferedReader(newInputStreamReader(kkSocket.getInputStream(),"ISO-8859-1"));
这样,Java将正确地将字节解释为您想要的字符
这是必需的,因为0xFF是UTF-8中的最后一个字节,是无效字符。另一个选项是将Java要使用的默认字符集设置为ISO-8859-1
我记得Java从抛出异常变为用替换字符替换字符(INT65533) 看看我的答案。。。这是因为它实际上是Unicode替换字符。