2011-03-30 76 views
2

就像标题所说,是有可能的成功WSASend呼叫与I/O完成端口相关联的未张贴比结束线程之外的其他原因完成一个插座上?是否有可能无法接收WSASend调用的完成?

我有一种奇怪的情况:它看起来像一个完成没有被公布为WSASend,这导致插槽泄露;应用程序认为发送仍然等待套接字并拒绝发布它。

的发送代码如下:

void CSocketServer::Write(
    Socket *pSocket, 
    CIOBuffer *pBuffer) const 
{ 
    pSocket->AddRef(); 

    pBuffer->SetOperation(IO_Write_Completed); 
    pBuffer->SetupWrite(); 
    pBuffer->AddRef(); 

    DWORD dwFlags = 0; 
    DWORD dwSendNumBytes = 0; 

    if (SOCKET_ERROR == ::WSASend(
     pSocket->m_socket, 
     pBuffer->GetWSABUF(), 
     1, 
     &dwSendNumBytes, 
     dwFlags, 
     pBuffer, 
     NULL)) 
    { 
     DWORD lastError = ::WSAGetLastError(); 

     if (ERROR_IO_PENDING != lastError) 
     { 
      pSocket->OnConnectionError(WriteError, pBuffer, lastError); 

      pSocket->WriteCompleted(); // this pending write will never complete... 

      pSocket->Release(); 
      pBuffer->Release(); 
     } 
    } 
    // Note: even if WSASend returns SUCCESS an IO Completion Packet is 
    // queued to the IOCP the same as if ERROR_IO_PENDING was returned. 
    // Thus we need no special handling for the non error return case. 
    // See http://support.microsoft.com/default.aspx?scid=kb;en-us;Q192800 
    // for details. 
} 

回答

2

你使用任何时髦的新功能,如关闭落成使用FILE_SKIP_COMPLETION_PORT_ON_SUCCESS成功的电话?

您是否正在对您的发送进行任何形式的流量控制,或者您是否只是随时随地发送流量控制,而且您只是想随时随地发送流量控制?你可能会看到的只是一个SLOW完成,因为TCP堆栈正在进行拥塞控制并且不能发送你的数据。如果您继续以不受控制的方式发送数据,则通常可能会出现完成开始花费的时间越来越长的情况。特别是如果你发送数据的速度比TCP连接成功地将数据发送到另一端的速度快,特别是TCP窗口不那么大时。看到这里:http://www.lenholgate.com/blog/2008/07/write-completion-flow-control.html了解更多信息。

当然,它可能只是您发送逻辑中的一个错误,您能发布一些代码吗?

请注意,在使用FILE_SKIP_COMPLETION_PORT_ON_SUCCESS时,存在WSARecv()和UDP(因此与您的问题无关)的已知错误,它提供了描述数据报是否大于您提供的缓冲区和呼叫将产生一个WSAEMOREDATA;在这里看到:http://www.lenholgate.com/blog/2010/01/file-skip-completion-port-on-success-and-datagram-socket-read-errors.html

+0

我想我可能会使用你的服务器架构的5-7岁的,重大的修改版本。这不是一个缓慢完成,因为没有拥塞,但我看到一些永远不会被释放的套接字。倾销他们表明他们有一个参考和一个杰出的写作。如果我等待24小时并再次倾倒它们,这些插座仍然存在。这可能是一个逻辑上的错误,我似乎无法找到它。 – 2011-03-31 11:43:49

+0

我不提供对免费代码的支持,甚至更少;)对​​于它的重大修改版本,但它听起来像是一个逻辑错误。发布发送发送的代码? – 2011-03-31 12:22:57

+0

虽然我粘贴了“写入”功能,但我不确定它有多少是你的。另一个线程向I/O线程发布'IO_Write_Request'操作,并处理它并输入此函数。 – 2011-03-31 13:20:08

1

它可以防止一个完成端口可以发布通过设定的低比特的OVERLAPPED结构的有效hEvent

从文档GetQueuedCompletionStatus

即使你已经通过了功能与 完成端口和一个有效的OVERLAPPED 结构相关联的 文件句柄,应用程序可以防止 完成端口的通知。这是 通过指定一个有效事件 句柄 OVERLAPPED结构的hEvent构件,并设置其 低位比特进行。其低位被设置的有效事件句柄 保持I/O 完成排队到 完成端口。

+0

有趣。考虑到他使用的代码,除非他已经'大量修改'这个区域,否则这不太可能是他的问题的原因......他所从事的基本代码根本不使用重叠结构中的事件。 – 2011-04-01 11:21:26

相关问题