c - 是否有可能无法收到 WSASend 调用的完成信息?

标签 c winapi tcp winsock2 iocp

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

最佳答案

您是否正在使用任何时髦的新功能,例如使用 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 关闭成功调用的完成功能? ?

您是否对发送进行任何形式的流量控制,或者您只是在您愿意的时候发送,并且按照您想要的频率发送?您可能看到的只是缓慢的完成,因为 TCP 堆栈正在执行拥塞控制并且还无法发送您的数据。如果您继续以不受控制的方式发送数据,您通常会遇到完成时间开始变得越来越长的情况。特别是如果您发送数据的速率比 TCP 连接成功将数据发送到另一端的速率快,尤其是当 TCP 窗口不是那么大时。参见这里:http://www.lenholgate.com/blog/2008/07/write-completion-flow-control.html了解更多信息。

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

请注意,使用 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 时,WSARecv() 和 UDP 存在一个已知错误(因此与您的问题完全无关)如果数据报大于您提供的缓冲区和WSARecv(),则给出您所描述的情况调用会生成 WSAEMOREDATA ;参见这里:http://www.lenholgate.com/blog/2010/01/file-skip-completion-port-on-success-and-datagram-socket-read-errors.html

关于c - 是否有可能无法收到 WSASend 调用的完成信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5486676/

相关文章:

c - 在相对于指针的地址处存储地址或 NULL

c - Ncurses 在后台停止进程

c - 树莓派上的结构段错误gcc

c - 在 Win32 中使用 C 语言中的扩展 ASCII 归类表

sql-server - 无法使用SQL Server ODBC驱动程序执行同义词存储过程;与OLEDB一起使用

c++ - 在Windows中通过串口写入二进制数据

tcp - SMTP 是基于 TCP 还是 UDP?

将多个 C 源文件编译成一个唯一的目标文件

C# - 无需端口转发即可远程控制 PC(如 TeamViewer)

套接字的描述符可以转换为文件指针吗?