📄 asyncsocketex.cpp
字号:
if (error)
return FALSE;
for (res = res0; res; res = res->ai_next)
if (Bind(res->ai_addr, res->ai_addrlen))
{
ret = TRUE;
break;
}
else
continue ;
p_freeaddrinfo(res0);
return ret ;
}
else if (!lpszAscii && m_SocketData.nFamily == AF_INET6)
{
SOCKADDR_IN6 sockAddr6;
memset(&sockAddr6, 0, sizeof(sockAddr6));
sockAddr6.sin6_family = AF_INET6 ;
sockAddr6.sin6_addr = in6addr_any ;
sockAddr6.sin6_port = htons((u_short)nSocketPort);
return Bind((SOCKADDR*)&sockAddr6, sizeof(sockAddr6));
}
else if (!lpszAscii && m_SocketData.nFamily == AF_INET)
{
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.sin_family = AF_INET ;
sockAddr.sin_addr.s_addr = INADDR_ANY ;
sockAddr.sin_port = htons((u_short)nSocketPort);
return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
}
else
return FALSE ;
}
BOOL CAsyncSocketEx::Bind(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{
if (!bind(m_SocketData.hSocket, lpSockAddr, nSockAddrLen))
return TRUE;
else
return FALSE;
}
void CAsyncSocketEx::AttachHandle(SOCKET hSocket)
{
ASSERT(m_pLocalAsyncSocketExThreadData);
VERIFY(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->AddSocket(this, m_SocketData.nSocketIndex));
#ifndef NOSOCKETSTATES
SetState(attached);
#endif //NOSOCKETSTATES
}
void CAsyncSocketEx::DetachHandle(SOCKET hSocket)
{
ASSERT(m_pLocalAsyncSocketExThreadData);
if (!m_pLocalAsyncSocketExThreadData)
return;
ASSERT(m_pLocalAsyncSocketExThreadData->m_pHelperWindow);
if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow)
return;
VERIFY(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->RemoveSocket(this, m_SocketData.nSocketIndex));
#ifndef NOSOCKETSTATES
SetState(notsock);
#endif //NOSOCKETSTATES
}
void CAsyncSocketEx::Close()
{
#ifndef NOSOCKETSTATES
m_nPendingEvents = 0;
#endif //NOSOCKETSTATES
#ifndef NOLAYERS
if (m_pFirstLayer)
m_pFirstLayer->Close();
#endif //NOLAYERS
if (m_SocketData.hSocket != INVALID_SOCKET)
{
VERIFY(closesocket(m_SocketData.hSocket)!=SOCKET_ERROR);
DetachHandle(m_SocketData.hSocket);
m_SocketData.hSocket = INVALID_SOCKET;
}
if (m_SocketData.addrInfo)
{
p_freeaddrinfo(m_SocketData.addrInfo);
m_SocketData.addrInfo = 0;
m_SocketData.nextAddr = 0;
}
m_SocketData.nFamily = AF_UNSPEC;
delete [] m_lpszSocketAddress;
m_lpszSocketAddress = 0;
m_nSocketPort = 0;
#ifndef NOLAYERS
RemoveAllLayers();
#endif //NOLAYERS
delete [] m_pAsyncGetHostByNameBuffer;
m_pAsyncGetHostByNameBuffer = NULL;
if (m_hAsyncGetHostByNameHandle)
WSACancelAsyncRequest(m_hAsyncGetHostByNameHandle);
m_hAsyncGetHostByNameHandle = NULL;
m_SocketData.onCloseCalled = false;
}
BOOL CAsyncSocketEx::InitAsyncSocketExInstance()
{
//Check if already initialized
if (m_pLocalAsyncSocketExThreadData)
return TRUE;
DWORD id=GetCurrentThreadId();
m_sGlobalCriticalSection.Lock();
//Get thread specific data
if (m_spAsyncSocketExThreadDataList)
{
t_AsyncSocketExThreadDataList *pList=m_spAsyncSocketExThreadDataList;
while (pList)
{
ASSERT(pList->pThreadData);
ASSERT(pList->pThreadData->nInstanceCount>0);
if (pList->pThreadData->nThreadId==id)
{
m_pLocalAsyncSocketExThreadData=pList->pThreadData;
m_pLocalAsyncSocketExThreadData->nInstanceCount++;
break;
}
pList=pList->pNext;
}
//Current thread yet has no sockets
if (!pList)
{
//Initialize data for current thread
pList=new t_AsyncSocketExThreadDataList;
pList->pNext=m_spAsyncSocketExThreadDataList;
m_spAsyncSocketExThreadDataList=pList;
m_pLocalAsyncSocketExThreadData=new t_AsyncSocketExThreadData;
m_pLocalAsyncSocketExThreadData->nInstanceCount=1;
m_pLocalAsyncSocketExThreadData->nThreadId=id;
m_pLocalAsyncSocketExThreadData->m_pHelperWindow=new CAsyncSocketExHelperWindow;
m_spAsyncSocketExThreadDataList->pThreadData=m_pLocalAsyncSocketExThreadData;
}
}
else
{ //No thread has instances of CAsyncSocketEx; Initialize data
m_spAsyncSocketExThreadDataList=new t_AsyncSocketExThreadDataList;
m_spAsyncSocketExThreadDataList->pNext=0;
m_pLocalAsyncSocketExThreadData=new t_AsyncSocketExThreadData;
m_pLocalAsyncSocketExThreadData->nInstanceCount=1;
m_pLocalAsyncSocketExThreadData->nThreadId=id;
m_pLocalAsyncSocketExThreadData->m_pHelperWindow=new CAsyncSocketExHelperWindow;
m_spAsyncSocketExThreadDataList->pThreadData=m_pLocalAsyncSocketExThreadData;
m_hDll = LoadLibrary(_T("WS2_32.dll"));
if (m_hDll)
{
p_getaddrinfo = (t_getaddrinfo)GetProcAddress(m_hDll, "getaddrinfo");
p_freeaddrinfo = (t_freeaddrinfo)GetProcAddress(m_hDll, "freeaddrinfo");
if (!p_getaddrinfo || !p_freeaddrinfo)
{
p_getaddrinfo = 0;
p_freeaddrinfo = 0;
FreeLibrary(m_hDll);
m_hDll = 0;
}
}
}
m_sGlobalCriticalSection.Unlock();
return TRUE;
}
void CAsyncSocketEx::FreeAsyncSocketExInstance()
{
//Check if already freed
if (!m_pLocalAsyncSocketExThreadData)
return;
DWORD id=m_pLocalAsyncSocketExThreadData->nThreadId;
m_sGlobalCriticalSection.Lock();
ASSERT(m_spAsyncSocketExThreadDataList);
t_AsyncSocketExThreadDataList *pList=m_spAsyncSocketExThreadDataList;
t_AsyncSocketExThreadDataList *pPrev=0;
//Serach for data for current thread and decrease instance count
while (pList)
{
ASSERT(pList->pThreadData);
ASSERT(pList->pThreadData->nInstanceCount>0);
if (pList->pThreadData->nThreadId==id)
{
ASSERT(m_pLocalAsyncSocketExThreadData==pList->pThreadData);
m_pLocalAsyncSocketExThreadData->nInstanceCount--;
//Freeing last instance?
//If so, destroy helper window
if (!m_pLocalAsyncSocketExThreadData->nInstanceCount)
{
delete m_pLocalAsyncSocketExThreadData->m_pHelperWindow;
delete m_pLocalAsyncSocketExThreadData;
if (pPrev)
pPrev->pNext=pList->pNext;
else
m_spAsyncSocketExThreadDataList=pList->pNext;
delete pList;
// Last thread closed, free dll
if (!m_spAsyncSocketExThreadDataList)
{
if (m_hDll)
{
p_getaddrinfo = 0;
p_freeaddrinfo = 0;
FreeLibrary(m_hDll);
m_hDll = 0;
}
}
break;
}
break;
}
pPrev=pList;
pList=pList->pNext;
ASSERT(pList);
}
m_sGlobalCriticalSection.Unlock();
}
int CAsyncSocketEx::Receive(void* lpBuf, int nBufLen, int nFlags /*=0*/)
{
#ifndef NOLAYERS
if (m_pFirstLayer)
return m_pFirstLayer->Receive(lpBuf, nBufLen, nFlags);
else
#endif //NOLAYERS
return recv(m_SocketData.hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
}
int CAsyncSocketEx::Send(const void* lpBuf, int nBufLen, int nFlags /*=0*/)
{
#ifndef NOLAYERS
if (m_pFirstLayer)
return m_pFirstLayer->Send(lpBuf, nBufLen, nFlags);
else
#endif //NOLAYERS
return send(m_SocketData.hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
}
BOOL CAsyncSocketEx::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
{
#ifndef NOLAYERS
if (m_pFirstLayer)
{
BOOL res = m_pFirstLayer->Connect(lpszHostAddress, nHostPort);
#ifndef NOSOCKETSTATES
if (res || GetLastError()==WSAEWOULDBLOCK)
SetState(connecting);
#endif //NOSOCKETSTATES
return res;
} else
#endif //NOLAYERS
if (m_SocketData.nFamily == AF_INET)
{
USES_CONVERSION;
ASSERT(lpszHostAddress != NULL);
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
LPSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
{
if (m_pAsyncGetHostByNameBuffer)
delete [] m_pAsyncGetHostByNameBuffer;
m_pAsyncGetHostByNameBuffer=new char[MAXGETHOSTSTRUCT];
m_nAsyncGetHostByNamePort=nHostPort;
m_hAsyncGetHostByNameHandle=WSAAsyncGetHostByName(GetHelperWindowHandle(), WM_USER+1, lpszAscii, m_pAsyncGetHostByNameBuffer, MAXGETHOSTSTRUCT);
if (!m_hAsyncGetHostByNameHandle)
return FALSE;
WSASetLastError(WSAEWOULDBLOCK);
#ifndef NOSOCKETSTATES
SetState(connecting);
#endif //NOSOCKETSTATES
return FALSE;
}
sockAddr.sin_port = htons((u_short)nHostPort);
return CAsyncSocketEx::Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
}
else
{
if (!p_getaddrinfo)
{
WSASetLastError(WSAEPROTONOSUPPORT);
return FALSE;
}
USES_CONVERSION;
ASSERT( lpszHostAddress != NULL );
if (m_SocketData.addrInfo)
{
p_freeaddrinfo(m_SocketData.addrInfo);
m_SocketData.addrInfo = 0;
m_SocketData.nextAddr = 0;
}
addrinfo hints;
int error;
BOOL ret;
char port[10];
memset(&hints, 0, sizeof(addrinfo));
hints.ai_family = m_SocketData.nFamily;
hints.ai_socktype = SOCK_STREAM;
_snprintf(port, 9, "%lu", nHostPort);
error = p_getaddrinfo(T2CA(lpszHostAddress), port, &hints, &m_SocketData.addrInfo);
if (error)
return FALSE;
for (m_SocketData.nextAddr = m_SocketData.addrInfo; m_SocketData.nextAddr; m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next)
{
bool newSocket = false;
if (m_SocketData.nFamily == AF_UNSPEC)
{
newSocket = true;
m_SocketData.hSocket = socket(m_SocketData.nextAddr->ai_family, m_SocketData.nextAddr->ai_socktype, m_SocketData.nextAddr->ai_protocol);
if (m_SocketData.hSocket == INVALID_SOCKET)
continue;
m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
AttachHandle(m_SocketData.hSocket);
if (!AsyncSelect(m_lEvent))
{
if (newSocket)
{
DetachHandle(m_SocketData.hSocket);
closesocket(m_SocketData.hSocket);
m_SocketData.hSocket = INVALID_SOCKET;
}
continue;
}
}
else if (m_SocketData.hSocket == INVALID_SOCKET)
continue;
#ifndef NOLAYERS
if (m_pFirstLayer)
{
if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
{
if (newSocket)
{
m_SocketData.nFamily = AF_UNSPEC;
DetachHandle(m_SocketData.hSocket);
closesocket(m_SocketData.hSocket);
m_SocketData.hSocket = INVALID_SOCKET;
}
continue;
}
}
#endif //NOLAYERS
if (newSocket)
{
m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
if (!Bind(m_nSocketPort, m_lpszSocketAddress))
{
m_SocketData.nFamily = AF_UNSPEC;
DetachHandle(m_SocketData.hSocket);
closesocket(m_SocketData.hSocket);
m_SocketData.hSocket = INVALID_SOCKET;
continue;
}
}
if (!(ret = CAsyncSocketEx::Connect(m_SocketData.nextAddr->ai_addr, m_SocketData.nextAddr->ai_addrlen)) && GetLastError() != WSAEWOULDBLOCK)
{
if (newSocket)
{
m_SocketData.nFamily = AF_UNSPEC;
DetachHandle(m_SocketData.hSocket);
closesocket(m_SocketData.hSocket);
m_SocketData.hSocket = INVALID_SOCKET;
}
continue;
}
break;
}
if (m_SocketData.nextAddr)
m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next;
if (!m_SocketData.nextAddr)
{
p_freeaddrinfo(m_SocketData.addrInfo);
m_SocketData.nextAddr = 0;
m_SocketData.addrInfo = 0;
}
if (m_SocketData.hSocket == INVALID_SOCKET || !ret)
return FALSE;
else
return TRUE;
}
}
BOOL CAsyncSocketEx::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{
BOOL res;
#ifndef NOLAYERS
if (m_pFirstLayer)
res = SOCKET_ERROR!=m_pFirstLayer->Connect(lpSockAddr, nSockAddrLen);
else
#endif //NOLAYERS
res = SOCKET_ERROR!=connect(m_SocketData.hSocket, lpSockAddr, nSockAddrLen);
#ifndef NOSOCKETSTATES
if (res || GetLastError()==WSAEWOULDBLOCK)
SetState(connecting);
#endif //NOSOCKETSTATES
return res;
}
#ifdef _AFX
BOOL CAsyncSocketEx::GetPeerName( CString& rPeerAddress, UINT& rPeerPort )
{
#ifndef NOLAYERS
if (m_pFirstLayer)
return m_pFirstLayer->GetPeerName(rPeerAddress, rPeerPort);
#endif NOLAYERS
SOCKADDR* sockAddr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -