TCP客户端接收数据的大小是否有限制?使用TCP套接字通信时,服务器正在发送更多数据,但客户端仅获取了4K并停止。
TCP客户端接收数据的大小是否有限制?使用TCP套接字通信时,服务器正在发送更多数据,但客户端仅获取了4K并停止。
Receive
方法会读取所有可用的数据,但只会返回部分数据以便程序使用。请注意,它会读取缓冲区的大小限制。read()
和write()
不能保证读取和填充整个缓冲区或写出整个缓冲区。你可能需要缓冲发送和接收的内容,或在同步应用程序中实现send_all()
和receive_all()
函数。 - Eric des Courtis您可以考虑将读/写操作分割成多个调用。我过去确实遇到了一些与 TcpClient
相关的问题。为了解决这个问题,我们使用一个包装的流类,其中包含以下read/write
方法:
public override int Read(byte[] buffer, int offset, int count)
{
int totalBytesRead = 0;
int chunkBytesRead = 0;
do
{
chunkBytesRead = _stream.Read(buffer, offset + totalBytesRead, Math.Min(__frameSize, count - totalBytesRead));
totalBytesRead += chunkBytesRead;
} while (totalBytesRead < count && chunkBytesRead > 0);
return totalBytesRead;
}
public override void Write(byte[] buffer, int offset, int count)
{
int bytesSent = 0;
do
{
int chunkSize = Math.Min(__frameSize, count - bytesSent);
_stream.Write(buffer, offset + bytesSent, chunkSize);
bytesSent += chunkSize;
} while (bytesSent < count);
}
//_stream is the wrapped stream
//__frameSize is a constant, we use 4096 since its easy to allocate.
TCP 理论上没有数据限制,但由于我们受到物理资源(即内存)的限制,像 Microsoft Winsock 这样的实现者利用了一种称为“TCP 窗口大小”的东西。
这意味着当您使用 Winsock 的 send() 函数发送某些内容时(并且没有在套接字处理程序上设置任何选项),数据将首先被复制到套接字的临时缓冲区。只有在接收方确认已经接收到该数据后,Winsock 才会再次使用此内存。
因此,如果您发送速度比释放速度快,可能会使此缓冲区过载,从而导致错误!