【问题标题】:What happens with TCP packets between two Socket.BeginReceive calls?两次 Socket.BeginReceive 调用之间的 TCP 数据包会发生什么情况?
【发布时间】:2010-04-08 03:59:57
【问题描述】:
我对套接字编程有疑问。我正在开发一个 TCP 数据包嗅探器。我正在使用 Socket.BeginAccept、Socket.BeginReceive 来捕获每个数据包,但是当收到数据包时,我必须处理一些事情。这是一个快速操作,但需要几毫秒,然后再次调用 BeginReceive。
我的问题是,如果在我处理过程中发送了一些数据包,但没有调用 BeginReceive,会发生什么情况?数据包丢失了,还是内部缓冲了?有限制吗?
【问题讨论】:
标签:
c#
sockets
tcp
packets
beginreceive
【解决方案1】:
在 linux 世界中,内核会为你缓冲它们——我假设 windows 世界会做同样的事情。但最终正如 deltreme 所说,缓冲区会溢出(肯定有限制),并且有可能会默默地丢弃数据。
如果您正在处理每个数据包几毫秒的重量级任务,那么您可能需要考虑使用线程池来释放网络线程。 IE。您的网络线程应该做的就是抓取数据包并将其扔到队列中以供另一个线程处理,然后返回到网络上进行侦听。另一个线程/线程可以从队列中抓取这些数据包并处理它们——好消息是您甚至可以一次处理多个数据包,从而节省一些开销。在这里,您的队列将充当缓冲区,您可以控制希望它有多大,并且可以定义自己的丢弃策略。
【解决方案3】:
TCP 为您提供可靠的流,因此数据不会丢失(假设底层网络没有故障)。
两端的操作系统都有缓冲区,当您不读取字节时,它们会处理这些字节。这些缓冲区的大小是有限的,如果它们被填满,TCP 就会进行流量控制——本质上,发送端会发现缓冲区已满并停止发送,直到有更多空间可用。