问题:损坏的TCP段。
我在SocketChannel中反复发送一系列ByteBuffers。顺序如下:
\r\n
length of chunk (example: fff)
\r\n
chunk data (rubbish, a 1000 - 5000 character long string)
\r\n
length of next chunk (example: fff)
\r\n
next chunk data (rubbish, a 1000 - 5000 character long string)
...
我希望你能看到这种模式。网络级别的MTU大约为1500,因此它将创建TCP段以通过“块数据”发送。
段中的问题是:以某种方式(?),随机(?),段(其有效载荷)以\ r \ n开头,而不是首先从“块数据”开始的剩余字节。
所以你得到了例子:
(segment 1)
\r\n
length of chunk (example: fff)
\r\n
chunk data (456 bytes)
(segment 2)
\r\n
chunk data (remaining 156 bytes)
length of next
\r\n
而不是:
(segment 1)
\r\n
length of chunk (example: fff)
\r\n
chunk data (456 bytes)
(segment 2)
chunk data (remaining 156 bytes)
\r\n
length of next
\r\n
我想知道Java代码是否能够导致这种情况,知道我的“块数据”ByteBuffer正确发送,除了包含\ r \ n的ByteBuffer加入... 欢迎任何帮助,谢谢您的时间!
安德鲁
答案 0 :(得分:3)
我敢打赌你忽略了读或写的结果。 TCP不会丢失或损坏数据,Socket API或Java网络库也不会丢失或损坏。至少我在22年的网络编程和14年的Java中从未见过它。
答案 1 :(得分:0)
这不是因为网络问题,而是因为我们编码的方式。如果我们以块的形式读取和写入数据,则可能会因为上一个块而导致数据损坏。最后一个数据块读取可能是部分填充的,并且字节数组的默认值为0。 以下示例显示了它的解决方案
ObjectOutputStream out = new ObjectOutputStream(
socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
//Something local returns DataInputStream from server
InputStream dataInputStream = local.downloadFile(fileToBeRead);
int chunkSize = 10000;
byte[] chunkByteArray = new byte[chunkSize];
int bytesRead = -1;
while ((bytesRead = dataInputStream.read(chunkByteArray)) != -1) {
if (bytesRead < chunkSize) {
System.out.println("Last Chunk is " + bytesRead);
chunkByteArray = getLastChunkByteArray(bytesRead,chunkByteArray);
}
out.write(chunkByteArray);
}
dataInputStream.close();
方法
private byte[] getLastChunkByteArray(int noOfBytesRead,
byte[] partialFilledChunk) {
byte[] lastChunk = new byte[noOfBytesRead];
for (int i = 0; i < noOfBytesRead; i++) {
lastChunk[i] = partialFilledChunk[i];
}
return lastChunk;
}