繁体   English   中英

SocketChannel.write(ByteBuffer [])“损坏”数据

[英]SocketChannel.write(ByteBuffer[]) “corrupting” data

问题:TCP段损坏。

我在SocketChannel中反复发送一系列ByteBuffer。 顺序如下:

\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加入...欢迎任何帮助,谢谢你的时间!

安德鲁

我敢打赌,您将忽略读取或写入的结果。 TCP不会丢失或破坏数据,套接字API或Java网络库也不会丢失或破坏数据。 至少在大约22年的网络编程和14年的Java中,我从未见过。

这不是因为网络问题,而是因为我们编码的方式。 如果我们按块读取和写入数据,则可能由于最后一个块而导致数据损坏。 读取的最后一个数据块可能会被部分填充,并且字节数组的默认值为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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM