如何在使用之前清除内部服务器套接字缓冲区的内容
Posted
技术标签:
【中文标题】如何在使用之前清除内部服务器套接字缓冲区的内容【英文标题】:How to clear the content of internal server socket buffer before using it 【发布时间】:2013-10-15 16:35:40 【问题描述】:如果我向我的套接字服务器发送大量数据包,它们将被收集在内部接收套接字缓冲区中。
当停止发送源并重新启动服务器时,之前发送的数据包被一一消耗。
是否有可能以某种方式重置内部套接字缓冲区。
我正在使用 UDP 套接字,代码是在 Windows 上用 C++ 编写的。
【问题讨论】:
将SO_SNDBUF
和SO_RCVBUF
设置为0怎么样?
我已经将它设置为 4 个字节,但没有帮助。
【参考方案1】:
您对应用程序执行的操作有问题,或者您为应用程序选择了错误的协议(在本例中为 UDP)。
UDP 不提供任何消息顺序或传递的保证。因此,很自然地,当您在同一端口上重新启动服务器时,您会读取旧数据。
我认为使用 TCP 您可以通过将 SO_LINGER 选项设置为 0 并设置 SO_REUSEADDRESS 以避免 TIME_WAIT 状态来避免这种情况。
【讨论】:
关于 UDP 可以,但是,如果我开始传输 100 条消息,每条消息 4 条,然后停止客户端。那么为什么在启动服务器后数据包就像客户端还活着一样。一定是缓冲区的原因。减少缓冲区它必须解决问题。我正在这样做,但没有运气。那么问题出在哪里。 TCP 无论如何都会避免它。滥用 SO_LINGER 选项来强制重置一点帮助也没有。 这不仅仅是你的缓冲区。一般来说,路由器和遍历链路中都会有数据报。 @MartinJames:正确。这就是 TCP 中的 TIME_WAIT 状态。但在UDP中无法避免【参考方案2】:不幸的是,由于 UDP 没有“连接”的概念,操作系统(或您)无法区分“旧”数据和“新”数据。
特别是在 Win32 上,有一个 SIO_FLUSH
ioctl,您可以将其传递给 WSAIoctl()
。这个我没试过,好像只和发送队列有关。
另请参阅:clean window socket internal buffer
【讨论】:
【参考方案3】:你的问题不清楚。如果您关闭套接字并创建一个新套接字,您将获得一个全新的套接字接收缓冲区,其中没有任何内容,而不是来自旧套接字的旧套接字缓冲区及其旧的待处理数据。但是,在绑定新套接字时,数据包可能仍在传输中,因此它们会立即出现在新的接收缓冲区中。对此你无能为力,也无能为力,这是正确的。
【讨论】:
我很抱歉地说,但我正在经历这个。我启动服务器然后启动客户端并开始发送。每个数据包都有一个编号。然后我关闭服务器和客户端。几秒钟后,我再次启动服务器。没有客户。我在同一 IP 和端口上的服务器正在接收之前发送的数据包。很奇怪,我同意你的看法,但不知道为什么会这样。没有挂起的进程或线程。一旦我减小了缓冲区的大小,问题就消失了。但是不明白如何计算正确的缓冲区大小。以上是关于如何在使用之前清除内部服务器套接字缓冲区的内容的主要内容,如果未能解决你的问题,请参考以下文章
Python中的UDP套接字:如何清除缓冲区并忽略oldes消息