CSocket

更新时间:2024-02-27 18:55

CSocket是MFC在CAsyncSocket基础上派生的一个同步阻塞Socket的封装类,它的定义包含在afxsock.h中。它是如何又把CAsyncSocket变成同步的,而且还能响应同样的Socket事件呢?

情况

PumpMessage会遇到下面几种情况:

1 提取出了(从消息队列中移出来Remove),用户正在使用的一个Socket发送的WM_SOCKET_NOTIFY消息和对应的 FD_XXX事件,返回True.

2 提取出了(从消息队列中移出来Remove),用户正在使用的一个Socket发送的WM_SOCKET_NOTIFY消息和对应的 FD_Close事件,返回True.

3 提取出了(从消息队列中移出来Remove),PumpMessage(..)设定的定时器的WM_TIMER消息,TimeOut事件为 CSocket的一个成员变量,m_nTimeOut=2000ms,返回True

4 用户调用了CancelBlockingCall() 设置错误代码为WSAEINTR(被中断了),返回False

5 用户一直没有取到用户正在使用的一个Socket发送的WM_SOCKET_NOTIFY消息和对应的FD_XXX事件,但是取到了同一个线程中的其他Socket的WM_SOCKET_NOTIFY消息及其对应的消息,则将这些消息,加入到一个辅助性的队列中去,以后处理.

6 没有取到任何WM_SOCKET_NOTIFY消息,则开始查看(不是取出来,而是查看)本线程的消息队列中是否有其它消息,如果有的话,调用虚函数OnMessagePending(),来处理这些消息(OnMessagePending()用户可以自定义。在阻塞时,用户想要处理的消息),如果没有,则调用WaitMessage()开始等待消息的到来.

说明

代码说明如下:

A 先看Connect,因为Connect的阻塞的实现和Accept,Receive,ReceiveFrom,Send,SendTo都有点不同.

也许你们会奇怪为何是ConnectHelper(...),而不是Connect(...).其实ConnectHelper(...)才是Connect(..)

调用

真正调用的东西,如下:

总结

CSocket模式与socket API模式的最大区别在于它实现了:

1、将socket事件消息化

2、用消息阻塞方式实现同步

3、用序列化方式读写数据以防止死锁,简化读取数据模型(流数据)。

多线程编程时,由于CSocket不能跨线程使用,所以,新建工作线程中会有一个CSocket对象,而该对象会重新与已知SOCKET句柄重新Attach,实现在新的线程中以CSocket对象的方式编程。

然后使用消息通信的方式,实现在新建线程中读写数据。

通过消息、线程事件等同步机制 实现UI线程与CSocket对象所在工作线程的通信,并不会影响UI的响应。

在BOOL CSocket::PumpMessages(UINT uStopFlag)中

看OnMessagePending:

但上面针对的都是当前线程的WM_PAIT消息,而不是跨线程的,而多线程模式下的SOCKET都是放在工作线程中执行的!

免责声明
隐私政策
用户协议
目录 22
0{{catalogNumber[index]}}. {{item.title}}
{{item.title}}