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里判断
看源码
_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) { }
时间: 2024-10-10 08:09:24