看别人的一个程序,不明白为什么关闭一个SOCKET需要这么复杂:
class CListenSocket : public CSocket
CClientSocket* pSock 
SOCKET hDeadSocket ;
MSG msg;
hDeadSocket = pSock->m_hSocket;
    pSock->ShutDown(2);
    pSock->Close();    msg.message= WM_SOCKET_DEAD;
    msg.wParam = hDeadSocket;    ::DispatchMessage(&msg);    delete pSock;
为什么需要这么复杂啊!还传递消息做什么。真是搞不懂!
请高手解析!

解决方案 »

  1.   

    传递socket关闭的消息给应用层吧..
      

  2.   

    关闭与客户连接的CClientSocket* pSock 后发出WM_SOCKET_DEAD消息,
    在WM_SOCKET_DEAD响应函数中处理一些相关工作
      

  3.   

    其实没这么复杂,他的代码之所以这复杂,可能跟他的设计有关系,它把SOCKET句柄通过消息传给窗口,是因为这个窗口里的一些功能要用到这个SOCKET句柄,比如,在主窗口的类里建了一个链表记录所有的SOCKET句柄,当这个SOCKET句柄关闭时,就要告诉主窗口在链表里删除这个SOCKET句柄。而这所以先SHUTDOWN,然后再CLOSE,是处于安全考虑,比如你关闭SOCKET的时候,正好有网络数据过来,这样数据就会丢失,SHUTDOWN可以告诉远程,我已经关闭了,不要再发数据了,我想应该是这样的。我一般直接CLOSE就OK了
      

  4.   

    只在CClientSocket的析构函数中找到如下一段
    MSG msg; // For the socket about to be closed.
    SOCKET hDeadSocket = m_hSocket; CAsyncSocket::Close(); msg.message= WM_SOCKET_DEAD;
    msg.wParam = m_hSocket; ::DispatchMessage(&msg); //MSG msg;
    CSocket::ProcessAuxQueue();
    while(::PeekMessage(&msg,NULL,
     WM_SOCKET_NOTIFY,WM_SOCKET_DEAD,PM_REMOVE))
    {
    ::DispatchMessage(&msg);
    if( (msg.message==WM_SOCKET_DEAD) &&
       ((SOCKET)msg.wParam==hDeadSocket))
     break;
    }还是觉得,这个函数什么也没有做!
      

  5.   

    int shutdown(
      SOCKET s,
      int how
    );这是 MSDN 中 shutdown 的原型。
    这个函数一般是用来执行 Socket 的“完美关闭”的。其中 how 的值可以是 SD_RECEIVE(禁止接收)、SD_SEND(禁止发送)和 SD_BOTH(全部禁止)。Socket 的完美关闭(MSDN 中叫“graceful closure”)分两步进行:第一步:
    客户端:
        调用 shutdown(hSocket, SD_SEND);
        shutdown 函数返回以后,这个 Socket 已经不能发送数据,但可以接收。
    服务端:
        收到 FD_CLOSE 通知。send 最后的数据。第二步:
    服务端:
        send 完数据以后,调用 shutdown(hSocket, SD_SEND);
        调用 closesocket 关闭 Socket 句柄。
    客户端:
        receive 数据。
        收到 FD_CLOSE。
        调用 closesocket 关闭 socket 句柄。总之,客户端用 SD_SEND 调用 shutdown 时,服务端就会收到 FD_CLOSE,反之亦然。当然,用 WSASendDisconnect 也可以达到这个目的。上面的代码中,how 取值为 2,是 SD_BOTH,这时候会全部关闭。所以没必要等待另一端返回数据,直接 close 就行了。单独用 SD_RECEIVE 来调用 shutdown,我不知道有什么意义。
    至于传递的消息,是用来模拟 FD_CLOSE 送出,其手法类似于 CAsyncSocket 的做法。