Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 是否可能不接收WSASend调用的完成?_C_Winapi_Tcp_Winsock2_Iocp - Fatal编程技术网

C 是否可能不接收WSASend调用的完成?

C 是否可能不接收WSASend调用的完成?,c,winapi,tcp,winsock2,iocp,C,Winapi,Tcp,Winsock2,Iocp,正如标题所说,对与I/O完成端口关联的套接字进行的成功的WSASend调用是否可能出于线程结束以外的任何原因而不发布完成 我遇到了一个奇怪的情况,它看起来好像没有为WSASend发布完成信息,这导致了套接字泄漏;应用程序认为套接字的发送仍处于挂起状态,并拒绝释放它 发送代码如下: void CSocketServer::Write( Socket *pSocket, CIOBuffer *pBuffer) const { pSocket->AddRef();

正如标题所说,对与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.
}

您是否正在使用任何时髦的新功能,例如使用
文件\u跳过\u完成\u端口\u打开成功
关闭成功呼叫的完成功能

您是在发送时进行任何形式的流量控制,还是只在您想发送的时候发送,并且发送频率随您的意愿而定?您可能会看到,由于TCP堆栈正在进行拥塞控制,无法发送您的数据,因此完成速度很慢。如果您继续以一种不受控制的方式发送数据,您通常会陷入一种情况,即完成过程开始花费越来越长的时间。尤其是当您以比TCP连接更快的速度发送数据时,尤其是当TCP窗口没有那么大时。请参阅此处:了解更多信息

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


请注意,在使用
FILE\u SKIP\u COMPLETION\u PORT\u ON\u SUCCESS
时,WSARecv()和UDP存在已知的错误(因此与您的问题无关),该错误给出了您描述的数据报是否大于您提供的缓冲区和
WSARecv()的情况
调用将生成一个
WSAEMOREDATA
;请参见此处:

可以通过设置重叠的
结构的有效
hEvent
的低位来防止完成端口过帐:

来自以下文件:

即使您已经传递了函数a 与文件关联的文件句柄 完成端口和有效的重叠端口 结构,应用程序可以防止 完成端口通知。这是 通过指定有效的事件来完成 的hEvent成员的句柄 重叠结构及其设置 低阶位。有效的事件句柄 其低阶位设置保持I/O 完成从排队到 完成端口


我想我可能正在使用一个5-7年的、经过大量修改的服务器框架版本。这不是一个缓慢的完成,因为没有拥塞,但我看到一些套接字从未释放。丢弃它们表明它们有一个参考文献和一篇优秀的文章。如果我等24小时,然后再将其转储,这些套接字仍然存在。它可能是某个地方的逻辑错误,我似乎找不到它。我不支持免费代码,甚至更少;)但是,这听起来确实像是一个逻辑错误。发布发送的代码?我已经粘贴了
Write
函数,但是我不确定有多少是你的。另一个线程向I/O线程发布一个
IO_Write_Request
操作,由I/O线程处理并进入此函数。是的,这几乎都是我的,不太可能有bug,因为很多人使用免费框架已经好几年没有问题了。我想这封信实际上并没有传达给同行?或者它正在通过服务器,但仍然没有“完成”?您可能只是在I/O池中出现死锁,或者丢失了I/O线程吗?池中只有一个I/O线程,所以这不应该是一个问题。我不确定对等方是否得到了写入,不幸的是,我无法在测试环境中重现这一点。不过,我可以冒昧地猜测,情况并非如此,因为这种情况总是发生在一个相当新的套接字上。完成的阅读次数从不超过2或3次。有趣。考虑到他所使用的代码,这不太可能是他问题的原因,除非他对该领域进行了大量“重大修改”。。。他使用的基本代码根本不在重叠结构中使用事件。