MFC教程(14)-- SOCKET类的设计和实现
2010-03-28 20:34:56 来源:WEB开发网socket对象的创建和捆绑
(1)Create函数
首先,讨论Create函数,分析socket句柄如何被创建并和CAsyncSocket对象关联。Create的实现如下:
BOOL CAsyncSocket::Create(UINT nSocketPort, int nSocketType,
long lEvent, LPCTSTR lpszSocketAddress)
{
if (Socket(nSocketType, lEvent))
{
if (Bind(nSocketPort,lpszSocketAddress))
return TRUE;
int nResult = GetLastError();
Close();
WSASetLastError(nResult);
}
return FALSE;
}
其中:
参数1表示本socket的端口,缺省是0,如果要创建数据报的socket,则必须指定一个端口号。
参数2表示本socket的类型,缺省是SOCK_STREAM,表示面向连接类型。
参数3是屏蔽位,表示希望对本socket监测的事件,缺省是FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE。
参数4表示本socket的IP地址字符串,缺省是NULL。
Create调用Socket函数创建一个socket,并把它捆绑在this所指对象上,监测指定的网络事件。参数2和3被传递给Socket函数,如果希望创建数据报的socket,不要使用缺省参数,指定参数2是SOCK_DGRM。
如果上一步骤成功,则调用bind给新的socket分配端口和IP地址。
(2)Socket函数
接着,分析Socket函数,其实现如下:
BOOL CAsyncSocket::Socket(int nSocketType, long lEvent,
int nProtocolType, int nAddressFormat)
{
ASSERT(m_hSocket == INVALID_SOCKET);
m_hSocket = socket(nAddressFormat,nSocketType,nProtocolType);
if (m_hSocket != INVALID_SOCKET)
{
CAsyncSocket::AttachHandle(m_hSocket, this, FALSE);
return AsyncSelect(lEvent);
}
return FALSE;
}
其中:
参数1表示Socket类型,缺省值是SOCK_STREAM。
参数2表示希望监测的网络事件,缺省值同Create,指定了全部事件。
参数3表示使用的协议,缺省是0。实际上,SOCK_STREAM类型的socket使用TCP协议,SOCK_DGRM的socket则使用UDP协议。
参数4表示地址族(地址格式),缺省值是PF_INET(等同于AF_INET)。对于TCP/IP来说,协议族和地址族是同值的。
在socket没有被创建之前,成员变量m_hSocket是一个无效的socket句柄。Socket函数把协议族、socket类型、使用的协议等信息传递给WinSock API函数socket,创建一个socket。如果创建成功,则把它捆绑在this所指对象。
(3)捆绑(Attatch)
捆绑过程类似于其他Windows对象,将在模块线程状态的WinSock映射中添加一对新的映射:this所指对象和新创建的socket对象的映射。
另外,如果本模块线程状态的“socket窗口”没有创建,则创建一个,该窗口在异步操作时用来接收WinSock的通知消息,窗口句柄保存到模块线程状态的m_hSocketWindow变量中。函数AsyncSelect将指定该窗口为网络事件消息的接收窗口。
函数AttachHandle的实现在此不列举了。
更多精彩
赞助商链接