从输入流中读取的第二个数据包数据不完整,
Second packet read from input stream has incomplete data,
我是一个简单的服务器,它使用 TCP 接收字节,然后将它们保存到文件流中。通过多次测试,我发现收到的第一个数据包总是只有文件名,没有其他数据。收到的第二个数据包只有一个字节,它是输入文本文件的第一个字母。在此之后所有数据包都被正确发送,但我似乎无法弄清楚是什么弄乱了第二个数据包。最后一个数据包似乎也被写入了两次。谁能看到我做错了什么?这是一个示例 Input/Output:https://www.diffchecker.com/srclclrx
InputStream in = clntSock.getInputStream(); //server's input stream - gets data from the client
OutputStream out = clntSock.getOutputStream(); //server's output stream - server sends data to the client
byte[] byteBuffer = new byte[BUFSIZE];
int count = in.read(byteBuffer, 0, BUFSIZE);
String firstRead = new String(byteBuffer, 0, count);
int fileNameEnd = firstRead.indexOf("\r\n");
String fileName = firstRead.substring(0, fileNameEnd);
FileOutputStream fout = new FileOutputStream(fileName); //unzipped file output stream
int contentBegin = fileNameEnd+2;
byte[] oldBuffer = Arrays.copyOfRange(byteBuffer, contentBegin, count);
int oldCount = count-contentBegin;
String oldString = new String(byteBuffer, contentBegin, count-contentBegin, "US-ASCII");
while((count = in.read(byteBuffer, 0, BUFSIZE)) != -1) { // read from origin's buffer into byteBuffer until origin is out of data
String newString = new String(byteBuffer, 0, count, "US-ASCII");
String combinedString = oldString + newString;
int index = combinedString.indexOf("--------MagicStringCSE283Miami");
if(index != -1){
System.out.println("Final Print");
byte[] combinedBuffer = concat(oldBuffer, byteBuffer);
for(int i=0; i<index; i++){
System.out.print((char)combinedBuffer[i]);
}
System.out.println("");
fout.write(combinedBuffer, 0, index);
fout.flush();
fout.close();
break;
}
System.out.println(+ oldCount);
fout.write(oldBuffer, 0, oldCount); //write the byteBuffer's data to the client via the zip output stream
fout.flush(); //push all data out of the zipOutputStream before continuing
if(count == 1){
for(int i=0; i<count; i++){
System.out.println((char)byteBuffer[i]);
}
}
oldBuffer = byteBuffer;
oldCount = count;
oldString = newString;
}
编辑:我的另一个特点是倒数第二个数据包始终只是“-”,然后最后一个数据包具有终止文件输出流的魔术字符串的其余部分。
TCP 中没有消息,也无法保证每个 read()
将 return 发送多少数据。只规定在阻塞模式下至少传输一个字节,除非发生错误。
这样做的后果之一是,如果不将 read()
的结果存储在变量中,测试它,然后使用它来界定处理的数据量,就不可能编写正确的网络代码。
你的期望有问题。
你真的确定你正在获取你收到的数据的全部内容吗?
while((count = in.read(byteBuffer, 0, BUFSIZE)) != -1) { // read from origin's buffer into byteBuffer until origin is out of data
add logic here to print count
add logic here to print the content of the byteBuffer
}
很可能在您的逻辑中您滥用了接收到的数据并以某种方式丢失了部分数据。
例如,您声称只收到“-”的第二个数据包的计数是否等于 1? TCP 确实可能就是这种情况,但您确实必须验证您确实在处理收到的所有内容。根据您的解释,我认为您正在丢弃数据,实际上并没有正确处理它。
我是一个简单的服务器,它使用 TCP 接收字节,然后将它们保存到文件流中。通过多次测试,我发现收到的第一个数据包总是只有文件名,没有其他数据。收到的第二个数据包只有一个字节,它是输入文本文件的第一个字母。在此之后所有数据包都被正确发送,但我似乎无法弄清楚是什么弄乱了第二个数据包。最后一个数据包似乎也被写入了两次。谁能看到我做错了什么?这是一个示例 Input/Output:https://www.diffchecker.com/srclclrx
InputStream in = clntSock.getInputStream(); //server's input stream - gets data from the client
OutputStream out = clntSock.getOutputStream(); //server's output stream - server sends data to the client
byte[] byteBuffer = new byte[BUFSIZE];
int count = in.read(byteBuffer, 0, BUFSIZE);
String firstRead = new String(byteBuffer, 0, count);
int fileNameEnd = firstRead.indexOf("\r\n");
String fileName = firstRead.substring(0, fileNameEnd);
FileOutputStream fout = new FileOutputStream(fileName); //unzipped file output stream
int contentBegin = fileNameEnd+2;
byte[] oldBuffer = Arrays.copyOfRange(byteBuffer, contentBegin, count);
int oldCount = count-contentBegin;
String oldString = new String(byteBuffer, contentBegin, count-contentBegin, "US-ASCII");
while((count = in.read(byteBuffer, 0, BUFSIZE)) != -1) { // read from origin's buffer into byteBuffer until origin is out of data
String newString = new String(byteBuffer, 0, count, "US-ASCII");
String combinedString = oldString + newString;
int index = combinedString.indexOf("--------MagicStringCSE283Miami");
if(index != -1){
System.out.println("Final Print");
byte[] combinedBuffer = concat(oldBuffer, byteBuffer);
for(int i=0; i<index; i++){
System.out.print((char)combinedBuffer[i]);
}
System.out.println("");
fout.write(combinedBuffer, 0, index);
fout.flush();
fout.close();
break;
}
System.out.println(+ oldCount);
fout.write(oldBuffer, 0, oldCount); //write the byteBuffer's data to the client via the zip output stream
fout.flush(); //push all data out of the zipOutputStream before continuing
if(count == 1){
for(int i=0; i<count; i++){
System.out.println((char)byteBuffer[i]);
}
}
oldBuffer = byteBuffer;
oldCount = count;
oldString = newString;
}
编辑:我的另一个特点是倒数第二个数据包始终只是“-”,然后最后一个数据包具有终止文件输出流的魔术字符串的其余部分。
TCP 中没有消息,也无法保证每个 read()
将 return 发送多少数据。只规定在阻塞模式下至少传输一个字节,除非发生错误。
这样做的后果之一是,如果不将 read()
的结果存储在变量中,测试它,然后使用它来界定处理的数据量,就不可能编写正确的网络代码。
你的期望有问题。
你真的确定你正在获取你收到的数据的全部内容吗?
while((count = in.read(byteBuffer, 0, BUFSIZE)) != -1) { // read from origin's buffer into byteBuffer until origin is out of data
add logic here to print count
add logic here to print the content of the byteBuffer
}
很可能在您的逻辑中您滥用了接收到的数据并以某种方式丢失了部分数据。 例如,您声称只收到“-”的第二个数据包的计数是否等于 1? TCP 确实可能就是这种情况,但您确实必须验证您确实在处理收到的所有内容。根据您的解释,我认为您正在丢弃数据,实际上并没有正确处理它。