天天看点

windows下网络编程(二)——MFC CAsyncSocket

CAsyncSocket 类是在很低的层次上对windows socket API进行了封装,它的成员函数和winsock API的函数调用直接对应,一个CAsyncSocket对象代表了一个windows套接字,它是网络通信的端点。该类将根据不同的windows套接字消息嗲用CAsyncSocket类的回调函数。

如果熟悉网络通信细节,仍希望充分利用winsock API编程的灵活性,并能安全的控制程序,同时还希望利用windows对网络事件通知的回调函数的便利,就应该使用CAsyncSocket类进行编程。同时必须自己处理阻塞问题、字节顺序问题和字符串转换问题。

CAsyncSocket类采用了windows socket中的WSAAsyncSelect模型。

一般步骤:

服务端

CAsyncSocket m_server;
if (m_server.Create(m_iPort) == FALSE)
	{
		MessageBox(L"server socket create failed");
		return;
	}
	

	if (m_server.Listen() == FALSE)
	{
		MessageBox(L"server socket listen failed");
		return;
	}
           

至于为什么没有bind,是因为create函数里已经做了bind工作。详见sockcore.cpp。

客户端

if (m_client.Create() == FALSE)
	{
		MessageBox(L"client socket create failed");
		return;
	}
	if (m_client.Connect(L"127.0.0.1",m_iPort) == FALSE)
	{
		MessageBox(L"client socket connect failed");       //此处不能通过返回值来直接判断连接失败,因为此socket是异步的
		return;
	}
           

注意看注释,所以代码不能这样判断是否连接成功。要重载OnConnect,然后在函数中来判断是否连接成功

void CMyAsyncSocket::OnConnect(int nErrorCode)
{
	// TODO: Add your specialized code here and/or call the base class
	if (nErrorCode == 0)
	{
		AfxMessageBox(L"connect success");
	}

	CAsyncSocket::OnConnect(nErrorCode);
}
           

CAsyncSocket编程注意问题:

  • 阻塞处理。CAsyncSocket对象专用于异步操作,不支持阻塞工作模式,如果应用程序需要支持阻塞操作,必须自己解决。
  • 字节顺序的转换。在不同的结构类型的计算机之间进行数据传输时,可能会有计算机之间字节存储顺序不一致的情况,需要自己对不用的字节顺序进行转换。
  • 字符串转换 同样不同结构类型的计算机的字符串顺序也可能不同,需要自行转换。

Reference:网络编程CAsyncSocket类