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对象,运行在独立的线程中。
|