CSocket为什么不流行呢?

来源:互联网 发布:java项目视频下载 编辑:程序博客网 时间:2024/04/29 02:03

 

MFC提供了一个方便UDP,TCP通讯的类CSocket,多年前就会用它来进行通讯了,然而在实际的项目中,没有见到过用CSocket的,用得最多的还是最原始的select模型,为什么呢?

经过今天的跟踪CSocket代码,觉得有以下原因导致了它很少被用的原因。

 

原因一:CSocket必须有Afx的支持

不需要定义CWinApp的对象

CSocket所在的可执行文件,dll或者exe,不管是Win32控制台还是窗口程序,还是普通的控制台程序,都需要利用AfxWinInit来初始化AfxGetModuleState()->m_hCurrentInstanceHandle,否则创建接收事件窗口的时候会失败

还需要调用用AfxSocketInit来保证AfxGetModuleThreadState()->m_pmapSocketHandle不为空,如果它为空了,当TCP服务端调用Accept函数的时候会调用CAsyncSocket::AttachHandle,这个函数里面会用到m_pmapSocketHandle来存储socket。

 

 

原因二:如果为TCP服务端CSocket::Create和CSocket::Listen必须在同一个线程里面调用,如果是TCP客户端CSocket::Create和CSocket::Connect必须在同一个线程里面调用

为什么有这个限制呢?

CSocket::Create创建了一个窗口,这个窗口的句柄将接收到socket事件,句柄保存到了CSocket::Create所在的线程的线程变量中,这个线程变量通过AfxGetModuleThreadState()->m_hSocketWindow可以访问,如果Create函数和Listen不在同一个线程调用,会导致后者所在的线程的m_hSocketWindow为NULL,然后代码会报错

 

原因三:必须存在一个消息循环,而且此消息循环必须和CSocket::Create在同一个线程里面

因为CSocket默认依靠窗口消息来处理OnAccept,OnReceive等消息的,如果不定义消息循环,将无法收到这些消息,因为GetMessage只能接收当前线程消息,如果消息循环和Create不在同一个线程里面,将无法得到需要收到的消息。

 

 

原因四:产生了一个窗体

因为采用了窗体来接受消息,所以必须建立窗体,虽然可以设置成别的模式

 

虽然很多人不在实际项目中用CSocket,但是可以看得出CSocket还是经过了精心设计了的,包括需要的窗体句柄被存储到了线程变量中,线程变量通过TLSAlloc,TLSGetValue,TLSSetValue来得到的,从分析CSocket的过程中了解了一些以前还很模糊的东西,越来越觉得微软设计得强大了

原创粉丝点击