我的一片天

我的一片天
posts - 27, comments - 12, trackbacks - 0, articles - 16
   :: 首页 :: 新随笔 :: 联系 ::  :: 管理

CAsyncSocket异步机制

Posted on 2008-03-21 12:58 xyz 阅读(577) 评论(0)  编辑 收藏 引用 所属分类: VC6
CAsyncSocket异步机制
当你获得了一个异步连接后,实际上你扫除了发送动作与接收动作之
间的依赖性。所以你随时可以发包,也随时可能收到包。发送、接收
函数都是异步非阻塞的,顷刻就能完成,所以收发交错进行着,你可
以一直工作,保持很高的效率。

但是,正因为发送、接收函数都是异步非阻塞的,所以仅调用它们并
不能保障发送或接收的完成。

例如发送函数Send,调用它可能有3种结果:错误、部分完成、全部完
成。其中错误又分两种情况:一种是由各种网络问题导致的失败,你
需要马上决定是放弃本次操作,还是启用某种对策;另一种是“忙”,
你实际上不用马上理睬。你需要调用GetLastError来判断是哪种情况,
GetLastError返回WSAEWOULDBLOCK,代表“忙”,为什么当你Send得
到WSAEWOULDBLOCK却不用理睬呢?因为CAsyncSocket会记得你的Send
WSAEWOULDBLOCK了,待发送的数据会写入CAsyncSocket内部的发送缓
冲区,并会在不忙的时候自动调用OnSend,发送内部缓冲区里的数据。
同样,如果Send只完成了一部分,你也不需要理睬,尚未发送的数据
同样会写入CAsyncSocket内部的发送缓冲区,并在适当的时候自动调
用OnSend完成发送。

与OnSend协助Send完成工作一样,OnRecieve、OnConnect、OnAccept
也会分别协助Recieve、Connect、Accept完成工作。这一切都通过消
息机制完成:

在你使用CAsyncSocket之前,必须调用AfxSocketInit初始化WinSock
环境,而AfxSocketInit会创建一个隐藏的CSocketWnd对象,由于这个
对象由Cwnd派生,因此它能够接收Windows消息。一方面它会接受各个
CAsyncSocket的状态报告,另一方面它能捕捉系统发出的各种SOCKET
事件。所以它能够成为高层CAsyncSocket对象与WinSock底层之间的
桥梁:例如某CAsyncSocket在Send时WSAEWOULDBLOCK了,它就会发送
一条消息给CSocketWnd作为报告,CSocketWnd会维护一个报告登记表,
当它收到底层WinSock发出的空闲消息时,就会检索报告登记表,然后
直接调用报告者的OnSend函数。所以前文所说的CAsyncSocket会自动
调用OnXxx,实际上是不对的,真正的调用者是CSocketWnd——它是
一个CWnd对象,运行在独立的线程中。
只有注册用户登录后才能发表评论。