问题描述
我想测试一个闭合的插座已经被同行被正常关闭,而不会产生双发送的延迟命中诱发 SIGPIPE
。
I'm trying to test for a closed socket that has been gracefully closed by the peer without incurring the latency hit of a double send to induce a SIGPIPE
.
其中假设这里是它的最后写入关闭是否正常是由对等关闭后立即插座/发送。像premature接近实际的错误处理,其他地方在code。
One of the assumptions here is that the socket if closed was gracefully closed by the peer immediately after it's last write / send. Actual errors like a premature close are dealt with else where in the code.
如果套接字仍处于打开状态,将有0个或多个字节的数据,我不真的想拔出插座缓冲区呢。
If the socket is still open, there will be 0 or more bytes data which I don't actually want to pull out of the socket buffer yet.
我在想,我可以打电话给 INT RET =的recv(的sockfd,BUF,1,MSG_DONTWAIT | MSG_PEEK);
来确定插座仍处于连接状态。如果它的连接,但有一个在缓冲区中没有数据,我会得到 1
与返回的errno == EAGAIN
并返回的sockfd再利用。如果它是由同行被正常关闭我去拿沤== 0
,并打开一个新的连接。
I was thinking that I could call int ret = recv(sockfd, buf, 1, MSG_DONTWAIT | MSG_PEEK);
to determine if the socket is still connected. If it's connected but there's no data in the buffer I'll get a return of -1
with errno == EAGAIN
and return the sockfd for reuse. If it's been gracefully closed by the peer I'll get ret == 0
and open a new connection.
我测试过这一点,它的似乎工作。然而,我怀疑是,当我的recv我的数据的最后一位,当同行 FIN
在到达我可以得到一个假阳性<$ C之间的一个小窗口$ C> EAGAIN 从我的测试的recv
。
I've tested this and it seems to work. However, I suspect there is a small window between when I recv the last bit of my data and when the peer FIN
arrives in which I could get a false-positive EAGAIN
from my test recv
.
难道这会咬我,或者是有这样做的更好的办法?
Is this going to bite me, or is there a better way of doing this?
推荐答案
OK,所以我跑了一些测试,这是我发现了什么。
OK, so I ran some more tests and this is what I found.
我把我的客户为发送 HTTP / 1.1连接:关闭
消息发送到服务器导致服务器关闭调用它的数据的一个写操作后。当我的客户完成了从一个GET事务中读取数据,将测试插座,看它是否采用上述方法,然后尝试发出另一个GET仍然是开放的。
I set my client up to send HTTP/1.1 Connection: close
messages to the server causing the server to call close after it's last write of data. When my client finished reading data from a GET transaction it would test the socket to see if it was still open using the above method and then attempt to issue another GET.
我发现的是,时间大约为30%,我的测试将在服务器的 FIN之前发生
赶到导致误报和失败的操作。
What I found is that approximately 30% of the time my test would occur before the server's FIN
arrived leading to false-positives and failed operations.
可能使这个相当可靠的唯一办法,说接近99%,将是介绍有关最后一次读取和未遂插座重用之间的连接等待时间人为的拖延 - 然而,这将pretty多少谋杀性能
Probably the only way to make this reasonably reliable, say close to 99% would be to introduce artificial delays related to the connection latency between the last read and the attempted socket reuse - however, that would pretty much murder performance.
所以,我不得不得出结论,而这个工具是有用的,它只能勉强左右。
So, I have to conclude that while this tool is useful, it's only marginally so.
这篇关于测试为封闭的插座的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!