要使用MFC的socket类,准备工作和使用API的socket类不同,在加载套接字库时,必须在app类的InitInstance()函数里调用AfxSocketInit函数,AfxSocketInit函数内部将调用WSAStartup函数加载套接字库,并且加载的是1.1版本的套接字库,使用AfxSocketInit函数不需要为工程链接ws2_32.lib库文件。如果AfxSocketInit函数调用成功,函数返回非0值,失败则返回0值。使用AfxSocketInit函数加载套接字库的另一个好处是在程序终止前会自动调用WSACleanup函数终止套接字库使用。因为程序调用了AfxSocketInit函数,所以还必须包含相应的头文件,在stdafx.h中添加#include "afxsock.h"。
MFC提供了两个封装socket的类,分别是CAsyncSocket 和 CSocket ,当中CSocket 是CAsyncSocket 的子类,这两个socket类有一个很大的区别,就是CAsyncSocket 是异步套接字而 CSocket是同步套接字,使用MFC的socket类有两个很明显的好处是:
1. 可以从这两个socket类中继承出自己的socket类,从而根据需要增加自己socket类的功能,而且要使用这两
个socket类,就一定需要从这两个类中继承出自己的类来使用,因为需要修改虚函数才能实现某些基本功能。
2. 可以方便的处理同步与异步问题。
对于第一个好处是显然易懂的,而对于第二个好处,就必须了解这些类的阻塞与非阻塞情况了。这里可以分为两大类:
第一类:从CAsyncSocket类继承下来的子类(不包括CSocket类与从CSocket类继承下来的子类),他们的阻
塞/非阻塞情况一样。
第二类:从CSocket类继承下来的子类,他们的阻塞/非阻塞情况一样。
具体情况:
继承了CAsyncSocket类的派生类:
由于CSocket类也是由CAsyncSocket类派生而来的,所以这里说的继承了CAsyncSocket类的派生类是自己建立的类,而不包括CSocket类和CSocket的派生类。例如自己建立一个CMySocket类,如下:
class CMySocket : public CAsyncSocket
那么这个CMySocket类的阻塞与非阻塞情况如下:
1.
Connect的时候,Connect()函数会马上返回WSAEWOULDBLOCK的错误码,然后程序继续往下执行,connect的具体操作就放在以后执行,等到connect的具体操作完了以后,无论有没有connect成功,最后都会调用On
2.
当有一个socket要连接CMySocket类的时候,CMySocket类的On
3.
当CMySocket类使用Send()函数发送数据的时候,On
4.
当有一个socket向CMySocket类发送数据的时候,CMySocket类的On
继承了CSocket类的派生类:
例如自己建立一个CYourSocket类,如下:
class CYourSocket : public CSocket
1.
Connect()的时候连接操作会马上执行,直到连接操作执行完毕后,Connect()函数才会返回,连接成功的话函数返回非0值,连接不成功就返回0值,函数返回后程序才继续往下执行。而On
2.
当有一个socket要连接CYourSocket类的时候,CYourSocket类的On
3.
当CYourSocket类使用Send()函数发送数据的时候,On
4.
当有一个socket向CYourSocket类发送数据的时候,CYourSocket类的On