Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/202.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JAVA上的TCP套接字-任意字节>;=128作为65533接收_Java_Android_Sockets_Tcp - Fatal编程技术网

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

JAVA上的TCP套接字-任意字节>;=128作为65533接收,java,android,sockets,tcp,Java,Android,Sockets,Tcp,我正在Android上实现一台服务器,我正在使用: while (!Thread.currentThread().isInterrupted()) { try { int r; String response = ""; while ((r = input.read()) > 0) { ... } ... } 我有两个问题。如果客户端向我发送一个值为0的字节,则服务器不会接收到该字节 第二个问

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

while (!Thread.currentThread().isInterrupted()) {
    try {
        int r;
        String response = "";
        while ((r = input.read()) > 0) {
        ...
        }
    ...
}
我有两个问题。如果客户端向我发送一个值为0的字节,则服务器不会接收到该字节

第二个问题是,如果字节值是128或更多,我会一直收到65533的值或11111101的二进制值

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

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

是的,但你忽略了它:

while ((r = input.read()) > 0) {
你可能是说:

while ((r = input.read()) > -1) {
第二个问题是,如果字节值是128或更多,我会一直收到65533的值或11111101的二进制值

不清楚您的意思是什么,但请记住,字节是用Java签名的-字节的范围是
[-128127]

几乎可以肯定的是,您不应该一次读取一个字节。相反,通常更适合使用字节数组,并调用

int bytesRead;
while ((bytesRead = input.read(buffer)) > 0)
或者,如果流是文本,则将输入流包装在
InputStreamReader
中。不要尝试自己进行二进制到文本的转换,因为它充满了容易遗漏的角落案例。

read()从输入流返回字节数。因此,0/0是有效的和良好的大小,特别是对于网络连接。到达流末尾时,read()返回-1。所以,您的代码应该是

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

它还应该在循环中有一些东西,以防止无休止的读取活动连接。一些超时-循环结束时,你得到零5分钟

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

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

第二个问题是,如果字节值是128或更多,我会一直收到65533的值或11111101的二进制值


不,你没有。对于大于等于128的任何字节值,都将得到一个负整数,但其中既没有65533也没有0b11111101。只有当您读入一个短字符,或将结果转换为短字符,或将其打印为短字符时,才会发生这种情况,即使在这种情况下,也只会发生在一个特定的字节值上,而不是所有的字节值都在128到255之间。

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

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

您收到的是65533,因为当一个值不能表示为真正的Unicode字符时,“Unicode替换字符”使用的是该整数。当前代码的确切行为将取决于系统上的默认字符编码,这同样不是您应该依赖的

我失败的代码如下(简化):

与您一样,当另一侧发送大于127的数字时,它正在打印:
获得:65533

要解决这个问题,只需调用
InputStream.read()
方法,而不是创建任何
读取器

InputStream is = socket.getInputStream();

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

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

否。
read()
的重载返回一个字节的数据,或-1表示流结束。但在阻塞模式下,零不是一个“好的大小”:它是一个不可能的大小,除非您为
read(byte[])、
read(byte[],int,int)
提供一个零长度缓冲区,他在这里都没有调用。对于第二个问题,是的。From
返回:读取的字符,范围为0到65535(0x00-0xffff)之间的整数,如果已到达流的末尾,则返回-1。
InputStream is = socket.getInputStream();

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