NetworkStream和TcpClient有多少缓冲区?

7

我们正在编写一个TCPServer和Client程序。TcpClient缓冲区有多大的空间?也就是说,在什么时候它会开始丢弃数据?我们试图确定TcpClient是否可以阻塞,或者它应该进入自己的后台线程(以便缓冲区不会变满)。

2个回答

8
你可以从 TcpClient.ReceiveBufferSizeTcpClient.SendBufferSize 获取缓冲区大小。
随着TCP层接收/确认(或未确认)数据,可用的缓冲区大小会有所变化。默认情况下,TcpClient是阻塞的。
在缓冲区已满的情况下不会丢失任何数据,但在错误条件下(例如对等方消失/崩溃/退出等),数据可能会被丢弃。

那它会一直接收数据直到电脑内存耗尽? - Earlz
4
不,TCP 提供流量控制。当缓冲区已满时,对端停止发送。 - nos
我也负责服务器,如果发生这种情况,那么服务器会发生什么?使用TcpServer时,它的缓冲区何时填满。 - Earlz
客户端和服务器端的情况是一样的。发送数据块时,当内部缓冲区已满且此时无法发送数据以清空这些缓冲区(例如,由于另一端尚未读取所有已发送的数据),则会发生阻塞。 - nos

4
MSDN文档称,TcpClient的发送接收缓冲区的默认大小为8192字节或8K。文档未指定这些缓冲区的最大限制。
正如您所知,使用其底层的NetworkStream对象通过TcpClient发送和接收数据。您可以控制这些操作是同步还是异步的。如果需要同步行为,请使用NetworkStream的Read和Write方法。如果需要异步行为,请使用BeginRead/EndRead和BeginWrite/EndWrite操作。
如果您作为前端应用程序的一部分接收数据,我强烈建议您在次线程中执行此操作,无论是使用异步方法还是在单独的线程中同步执行。这将使您的用户界面对用户响应,同时仍可以在后台处理数据的发送和接收。

我们还不确定是要异步执行,还是在后台线程同步执行。 - Earlz
@Earlz,我不确定这两者之间有很大的区别。异步方法(例如BeginRead())会在单独的线程上执行它们各自的AsyncCallback方法。归根结底,如果您正在尝试在处理用户界面输入的同时发送/接收数据,则需要使用第二个线程。 - Matt Davis
2
@MattDavis,那是一个常见的误解。.Net Async I/O方法实际上利用了一个叫做I/O完成端口的操作系统特性,因此在等待来自套接字、文件系统、命名管道或其他任何东西的I/O时,没有线程被阻塞或正在使用。 - Ben Lesh
@blesh,I/O完成端口只是将数据传输到系统中,数据仍然需要在某个地方进行处理。从技术上讲,数据可以在UI线程上进行处理,但我认为这是不好的做法,因为它会阻止UI对用户输入的响应。 - Matt Davis
足够正确,我以为你在谈论线程阻塞直到 I/O 返回。 - Ben Lesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接