CSocket的关闭为什么要这么复杂

jysh321 2007-04-30 10:39:57
看别人的一个程序,不明白为什么关闭一个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;
为什么需要这么复杂啊!还传递消息做什么。真是搞不懂!
请高手解析!
...全文
654 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lighterz 2007-05-01
  • 打赏
  • 举报
回复
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 的做法。
jysh321 2007-04-30
  • 打赏
  • 举报
回复
只在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;
}

还是觉得,这个函数什么也没有做!
mimong_lin 2007-04-30
  • 打赏
  • 举报
回复
来蹭点分

应该是与应用现对的。
第一步骤是为了确保关闭的时候,不会丢失数据的。

至于发送消息,可能是界面上的应用了,通知下用户。
wujiabao 2007-04-30
  • 打赏
  • 举报
回复
其实没这么复杂,他的代码之所以这复杂,可能跟他的设计有关系,它把SOCKET句柄通过消息

传给窗口,是因为这个窗口里的一些功能要用到这个SOCKET句柄,比如,在主窗口的类里建了

一个链表记录所有的SOCKET句柄,当这个SOCKET句柄关闭时,就要告诉主窗口在链表里删除

这个SOCKET句柄。而这所以先SHUTDOWN,然后再CLOSE,是处于安全考虑,比如你关闭SOCKET的

时候,正好有网络数据过来,这样数据就会丢失,SHUTDOWN可以告诉远程,我已经关闭了,不要

再发数据了,我想应该是这样的。我一般直接CLOSE就OK了
jysh321 2007-04-30
  • 打赏
  • 举报
回复
实在是没有看到应用层对这个消息的处理函数。
setsailgo 2007-04-30
  • 打赏
  • 举报
回复
关闭与客户连接的CClientSocket* pSock 后发出WM_SOCKET_DEAD消息,
在WM_SOCKET_DEAD响应函数中处理一些相关工作
lzd 2007-04-30
  • 打赏
  • 举报
回复
传递socket关闭的消息给应用层吧..

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧