Problem: Corrupt TCP segment.
I send a sequence of ByteBuffers over and over in a SocketChannel. The sequence is the following:
\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)
...
I hope you see the pattern. The MTU on network level is about 1500, so it'll create TCP segments to send over t开发者_运维知识库he "chunk data".
The problem in the segments is: Somehow(?), randomly(?), a segment (its payload) starts with \r\n instead of the remaining bytes from the "chunk data" first.
So you get for example:
(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
Instead of:
(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
I'd like to know if Java code is even able to cause that, knowing that my "chunk data" ByteBuffer sent correctly, except for the ByteBuffer containing \r\n that joins in... Any help is welcome, thank you for your time!
Andrew
I will bet that you are ignoring the result of a read or write. TCP does not lose or corrupt data and neither do the Socket APIs or the Java networking libraries. At least I've never seen it in about 22 years of network programming and 14 years of Java.
It is not because of network issue but with the way we coded. If we are reading and writing the data in chunks it may lead to data corruption because of last chunk. It may be possible the last data chunk read is partially filled and having default values as 0 for byte array. Following example shows the solution for it
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();
And the method
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;
}
精彩评论