JAVA上的TCP套接字 - 接收任何字节> = 128为65533

时间:2015-05-15 09:54:52

标签: java android sockets tcp

我在Android上实现了一个服务器,我正在使用:

while (!Thread.currentThread().isInterrupted()) {
    try {
        int r;
        String response = "";
        while ((r = input.read()) > 0) {
        ...
        }
    ...
}

我有两个问题。如果客户端向我发送一个值为0的字节,则服务器不会收到该字节。

第二个问题是,如果字节值为128或更多,我会继续接收值65533或二进制值11111101。

任何人都知道如何解决这些问题。我是JAVA网络的初学者。

4 个答案:

答案 0 :(得分:3)

我遇到了同样的问题,我在this问题中找到了答案:

  

您正在处理二进制数据,因此您应该使用原始流 - 不要将其转换为读取器,用于读取字符。

     

您正在接收65533,因为它是用于" Unicode替换字符的整数"当值不能表示为真正的Unicode字符时使用。当前代码的确切行为将取决于系统上的默认字符编码 - 这也不是您应该依赖的内容。

我的失败代码就像(简化):

InputStream is = socket.getInputStream();
BufferedReader input = new BufferedReader(new InputStreamReader(is));

int data = input.read();
if(data >=0){
    System.out.println("Obtained: "+data);
}

与您一样,当在另一方发送大于127的数字时,正在打印:Obtained: 65533

要解决此问题,只需调用InputStream.read()方法,而不是创建任何reader

InputStream is = socket.getInputStream();

int data = is.read();
if(data >=0){
    System.out.println("Obtained: "+data);
}

注意:可能此问题可能会被标记为与先前引用的问题重复。

答案 1 :(得分:0)

  

如果客户端向我发送一个值为0的字节,则服务器不会收到该字节。

是的,但是你忽略了它:

while ((r = input.read()) > 0) {

你可能意味着:

while ((r = input.read()) > -1) {
  

第二个问题是,如果字节值为128或更多,我会继续接收值65533或二进制值11111101。

目前还不清楚你的意思,但请记住,字节是用Java签名的 - 字节的范围是[-128, 127]

您几乎肯定不会一次读取一个字节。相反,拥有一个字节数组通常更合适,并调用

int bytesRead;
while ((bytesRead = input.read(buffer)) > 0)

或者,如果要将流设置为 text ,请将输入流包装在InputStreamReader中。 不要尝试自己进行二进制文本转换 - 它充满了易于错过的极端案例。

答案 2 :(得分:0)

  

如果客户端向我发送一个值为0的字节,则服务器不会收到该字节。

它由您的服务器主机接收,传递到您的服务器应用程序,并被您的应用程序代码忽略,因为您的循环在您收到它时停止。您应该在>= 0上循环,而不是> 0

  

第二个问题是,如果字节值为128或更多,我会继续接收值65533或二进制值11111101。

不,不。对于任何字节值&gt; = 128,您将得到负整数,但其中没有65533和0b11111101。只有当你读入一个short,或者将结果转换为short,或者将它打印为short时,才会发生这种情况,即使在这种情况下,它只发生在一个特定的字节值上,而不是全部在128到255之间。< / p>

答案 3 :(得分:-1)

read()返回输入流中的字节数。因此,0/0有效且大小合适,特别是对于网络连接。当达到流结束时,read()返回-1。所以,你的代码应该是

while((r = input.read())!= -1){}

它也应该在循环中有一些东西来防止无休止的阅读中的活着连接。一些超时 - 当你在5分钟内为零时循环结束。