Java 发送ACK会大大降低数据传输速度
意识到TCP校验和实际上是一个非常差的校验和,这促使我在数据块中包含一个额外的校验和(SHA-256),以验证服务器上数据的完整性,如果数据块损坏,请再次请求数据块。但ACK的加入大大降低了数据传输速率。在我的情况下(数据通过wifi传输),速度已从约90mbps降至约12mbps 客户:Java 发送ACK会大大降低数据传输速度,java,android,sockets,tcp,Java,Android,Sockets,Tcp,意识到TCP校验和实际上是一个非常差的校验和,这促使我在数据块中包含一个额外的校验和(SHA-256),以验证服务器上数据的完整性,如果数据块损坏,请再次请求数据块。但ACK的加入大大降低了数据传输速率。在我的情况下(数据通过wifi传输),速度已从约90mbps降至约12mbps 客户: SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("192.168.31.30", 3333)); ByteBuff
SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("192.168.31.30", 3333));
ByteBuffer byteBufferData = ByteBuffer.allocateDirect(1024 * 8);
ByteBuffer byteBufferACK = ByteBuffer.allocateDirect(1);
for (int i = 0; i < 1024; i++) {
// write data (payload + checksum (SHA-256))
socketChannel.write(byteBufferData);
byteBufferData.clear();
// read ACK
socketChannel.read(byteBufferACK);
byteBufferACK.clear();
// if (byteBufferACK.get() == XXX)
// ... retransmission byteBufferData
}
请注意,该代码是一个测试代码,并不打算传递任何有用的数据。它仅用于测试数据传输速率
我有两个问题:
因为你在等待。假设您和服务器之间有200毫秒的延迟。如果没有ack,您将尽快写入数据包,使带宽饱和,然后停止。对于ack,它看起来如下所示:
t=0 send 1st 8k
t=200 server recieves
t=205ish server sends ack
t=405 client recieves ack.
t=410ish client sends 2nd 8k
你浪费了50%的发送时间。事实上,我很惊讶事情没有变得更糟
TCP中有许多功能可以防止此类问题,包括滑动数据窗口(不发送一个数据包并确认它,发送N个数据包,服务器确认它接收到的数据包,允许丢失的数据包无序重新发送)。您正在错误地重新实现TCP,而且几乎肯定不应该这样做
如果要这样做,请不要使用TCP。使用UDP或原始套接字,并在此基础上编写新协议。您仍在使用TCP确认和校验和,因此您的校验和是多余的。TCP校验和是一种经过时间考验的优秀校验和。您认为需要SHA-256的要求是什么?密码校验和被设计用来抵御复杂的攻击。对于典型的通信信道错误,它们的性能并不比更有效的校验和好多少,有时甚至更差。
t=0 send 1st 8k
t=200 server recieves
t=205ish server sends ack
t=405 client recieves ack.
t=410ish client sends 2nd 8k