测试封闭的插座

时间:2010-03-14 11:10:58

标签: c tcp network-programming

我正在尝试测试一个已被对等方优雅关闭的已关闭套接字,而不会产生双重发送的延迟命中以诱导SIGPIPE

这里假设的一个假设是,在最后一次写入/发送之后,对等体在关闭时正好关闭了套接字。像过早关闭这样的实际错误会在代码中处理。

如果套接字仍处于打开状态,则会有0个或更多字节数据,我实际上并不想从套接字缓冲区中取出。

我在想我可以调用int ret = recv(sockfd, buf, 1, MSG_DONTWAIT | MSG_PEEK);来确定套接字是否仍然连接。如果它已连接但缓冲区中没有数据,我将返回-1 errno == EAGAIN并返回sockfd以供重用。如果它被对等方优雅地关闭,我将获得ret == 0并打开一个新连接。

我已经对此进行了测试,似乎可以正常工作。但是,我怀疑在我收集数据的最后一位和同行FIN到达之间有一个小窗口,我可以从我的测试中EAGAIN获得误报recv }。

这会咬我,还是有更好的方法呢?

3 个答案:

答案 0 :(得分:3)

好的,所以我又跑了一些测试,这就是我找到的。

我将客户端设置为向服务器发送HTTP/1.1 Connection: close消息,导致服务器在上次写入数据后调用close。当我的客户端从GET事务中读取数据时,它将测试套接字以查看它是否仍然使用上述方法打开,然后尝试发出另一个GET。

我发现,在服务器的FIN到达之前,我的测试大约有30%的时间会导致误报和操作失败。

可能使得这个相当可靠的唯一方法,比如接近99%,就是引入与最后一次读取和尝试的套接字重用之间的连接延迟相关的人为延迟 - 但是,这几乎可以谋杀性能。

所以,我必须得出结论,虽然这个工具很有用,但它只是略有不同。

答案 1 :(得分:0)

你控制另一端吗?执行“干净”关闭套接字的最可靠方法是让另一端发送某种“再见”消息。

答案 2 :(得分:0)

(略有“偏离主题”,对不起)。也许this discussion对你有帮助。它仍然没有回答你的“FIN”问题,但可以帮助你在程序发送时以更简单的方式对对等关闭做出反应。

再见