CSocket是对CAsyncSocket的一个再次封装,它将CAsyncSocket这种异步不阻塞的socket封装成了同步阻塞的socket。它的实现原理其实很简单,我们应该留意到在CAsyncSocket中Accept、Send、Receive函数被定义成了虚函数:
virtual BOOL Accept( CAsyncSocket& rConnectedSocket, SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL );
virtual int Receive( void* lpBuf, int nBufLen, int nFlags = 0 );
virtual int Send( const void* lpBuf, int nBufLen, int nFlags = 0 );
CSocket就是通过继承上述三个虚函数,在函数内部获取先调用WSAGetLastError获取错误,如果错误为WSAEWOULDBLOCK,说明IO操作未能完成,此时,它将进入消息循环,知道等到该IO事件完成为止。如果用伪代码,表示如下:
BOOL CSocket::Accept(…)
{
CAsyncSocket:: Accept(…)
{
if(WSAGetLastError()==WSAEWOULDBLOCK)
{
while(True)
{
MSG msg;
if(PeekMessage(&msg,WM_SOCKET_NOTIFY))
{
if(msg.message== WM_SOCKET_NOTIFY)
{
…
break;
}
}
}
}
…
}
…
}
…
}
其实对于使用者来讲使用CAsyncSocket和CSocket基本的编程步骤都是一致的,不同的只是它们两者之间的内部的处理逻辑。比如在上一文中,我们自定义了一个CMySocket类继承自CAsyncSocket,而如果我想要使用CSocket类,只需将上一文中的CMySocket父类改成CSocket:
class CMySocket : public CSocket
{
…
}
其他代码不需要任何的改动,我们就能得到功能相同的服务端和客户端。
Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本项目:
git clone git@github.com:HymanLiuTS/NetDevelopment.git
获取本文源代码:
git checkout NL58