2011-04-29 58 views
0

我已经编写了基于iocp机制的用于管理网络通信的复杂库。问题在于,当服务器通过调用API方法closesocket()关闭连接时,这些信息有时会以秒或甚至分钟的形式传输给客户端。我检测关闭连接的代码看起来像这样(简化):GetQueuedCompletionStatus延迟

ok = GetQueuedCompletionStatus(completion_port, &io_size, (PULONG_PTR)&context, &overlapped, 40); 

if (!ok) { 
    // something went broken 
    DWORD err = GetLastError(); 
    if (err == ERROR_CONNECTION_REFUSED) { 
     // connection failed 
    } else if (err == ERROR_SEM_TIMEOUT) { 
     // connection timeout 
    } else if (err == ERROR_NETNAME_DELETED) { 
     // connection closure - point of interest 
    } else if (err != WAIT_TIMEOUT) { 
     // unknown error 
    } 
} else { 
    // process incomming or outgoing data 
} 

这究竟是为什么?我需要立即知道连接关闭,以便能够连接到备份服务器(不是那么重的负载 - 因此发生断开连接)。

+0

不直接关系到你的问题,但你应该检查的重叠处理函数中的值以及返回代码。当重叠== NULL就意味着失败GetQueuedCompletionStatus时,重叠的时候!= NULL这意味着I/O请求失败。 – 2011-04-29 21:27:44

回答

0

我试图与灵儿参数进行试验,如莱恩写道,但这并没有帮助。在closesocket()之前添加了shutdown()函数的调用帮助了我。在分析到达客户端网络接口的数据包(使用WireShark)后,我发现RST数据包被FIN数据包所取代。奇怪的是,RST数据包没有延迟。因此操作系统知道连接关闭,而是由一些未知的原因,这个信息被转移到应用层非常滞后。我测量了10秒到4分钟之间的延迟。

0

你是如何关闭连接的?

如果你只是打电话closesocket()那么你正在启动关闭序列,这将试图确保当前等待处理的所有数据将到达目的地。这可能需要一些时间,尤其是在网络连接已经过载并且数据报已经丢失并且正在进行TCP重传的情况下。

如果您想立即关闭连接,并丢失任何待处理数据,请将逗号设置为0,然后关闭套接字。这将在连接上发出RST,你会更快。