我在Android上实现了一个服务器,我正在使用:
while (!Thread.currentThread().isInterrupted()) {
try {
int r;
String response = "";
while ((r = input.read()) > 0) {
...
}
...
}
我有两个问题。如果客户端向我发送一个值为0的字节,则服务器不会收到该字节。
第二个问题是,如果字节值为128或更多,我会继续接收值65533或二进制值11111101。
任何人都知道如何解决这些问题。我是JAVA网络的初学者。
答案 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分钟内为零时循环结束。