MFC CSocket和CAsyncSocket的连接
flyfish 2015-1-31
CSocket的Connect是阻塞的。
所以代码类似
if(!Connect())
{
}
判断成功还是失败
CAsyncSocket的Connect是非阻塞的
当调用CAsyncSocket::Connect连接一个服务器
虽然CAsyncSocket::Connect函数返回值是BOOL类型,
但代码不是
if(!Connect())
{
}
当连接操作完成,完成(complete)!=成功(successful ),应用程序将接收到OnConnect消息
所以需要重载OnConnect ,要在void 派生类::OnConnect(int nErrorCode)判断参数nErrorCode判断成功还是失败。
如果该类是派生于CSocket,也想要在OnConnect里判断
看源码
如果是CAsyncSocket::Connect
调用的是CAsyncSocket::Connect -》CAsyncSocket::ConnectHelper
如果是CSocket Connect时
CAsyncSocket::Connect -》CSocket::ConnectHelper 在这里产生了阻塞
阻塞与非阻塞的区别就在ConnectHelper
如果想要CSocket的派生类更改为CAsyncSocket的连接方式
flyfish 2015-1-31
CSocket的Connect是阻塞的。
所以代码类似
if(!Connect())
{
}
判断成功还是失败
CAsyncSocket的Connect是非阻塞的
当调用CAsyncSocket::Connect连接一个服务器
虽然CAsyncSocket::Connect函数返回值是BOOL类型,
但代码不是
if(!Connect())
{
}
当连接操作完成,完成(complete)!=成功(successful ),应用程序将接收到OnConnect消息
所以需要重载OnConnect ,要在void 派生类::OnConnect(int nErrorCode)判断参数nErrorCode判断成功还是失败。
如果该类是派生于CSocket,也想要在OnConnect里判断
看源码
_AFXSOCK_INLINE BOOL CAsyncSocket::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{ return ConnectHelper(lpSockAddr, nSockAddrLen); }
BOOL CAsyncSocket::ConnectHelper(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{
return connect(m_hSocket, lpSockAddr, nSockAddrLen) != SOCKET_ERROR;
}
BOOL CAsyncSocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
{
USES_CONVERSION_EX;
ASSERT(lpszHostAddress != NULL);
if (lpszHostAddress == NULL)
{
WSASetLastError (WSAEINVAL);
return FALSE;
}
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
LPSTR lpszAscii = T2A_EX((LPTSTR)lpszHostAddress, _ATL_SAFE_ALLOCA_DEF_THRESHOLD);
if (lpszAscii == NULL)
{
WSASetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
{
LPHOSTENT lphost;
lphost = gethostbyname(lpszAscii);
if (lphost != NULL)
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
{
WSASetLastError(WSAEINVAL);
return FALSE;
}
}
sockAddr.sin_port = htons((u_short)nHostPort);
return Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
}
BOOL CSocket::ConnectHelper(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{
if (m_pbBlocking != NULL)
{
WSASetLastError(WSAEINPROGRESS);
return FALSE;
}
m_nConnectError = -1;
if (!CAsyncSocket::ConnectHelper(lpSockAddr, nSockAddrLen))
{
if (GetLastError() == WSAEWOULDBLOCK)
{
while (PumpMessages(FD_CONNECT))
{
if (m_nConnectError != -1)
{
WSASetLastError(m_nConnectError);
return (m_nConnectError == 0);
}
}
}
return FALSE;
}
return TRUE;
}
如果是CAsyncSocket::Connect
调用的是CAsyncSocket::Connect -》CAsyncSocket::ConnectHelper
如果是CSocket Connect时
CAsyncSocket::Connect -》CSocket::ConnectHelper 在这里产生了阻塞
阻塞与非阻塞的区别就在ConnectHelper
如果想要CSocket的派生类更改为CAsyncSocket的连接方式
只要在派生类重载ConnectHelper 和 OnConnect
声明
virtual BOOL ConnectHelper(const SOCKADDR* lpSockAddr,int nSockAddrLen);
virtual void OnConnect(int nErrorCode);
实现
BOOL 派生类::ConnectHelper(const SOCKADDR* lpSockAddr,int nSockAddrLen)
{
return connect(m_hSocket, lpSockAddr, nSockAddrLen) != SOCKET_ERROR;
}
void 派生类::OnConnect(int nErrorCode)
{
}