asyncsocketex.cpp
来自「一个FTP下载的源代码。代码质量非常高」· C++ 代码 · 共 1,298 行 · 第 1/3 页
CPP
1,298 行
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_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;
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
{
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)
{
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));
}
}
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_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
BOOL bResult = GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen);
if (bResult)
{
rPeerPort = ntohs(sockAddr.sin_port);
rPeerAddress = inet_ntoa(sockAddr.sin_addr);
}
return bResult;
}
#endif //_AFX
BOOL CAsyncSocketEx::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
{
#ifndef NOLAYERS
if (m_pFirstLayer)
return m_pFirstLayer->GetPeerName(lpSockAddr, lpSockAddrLen);
#endif //NOLAYERS
if ( !getpeername(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen) )
return TRUE;
else
return FALSE;
}
#ifdef _AFX
BOOL CAsyncSocketEx::GetSockName(CString& rSocketAddress, UINT& rSocketPort)
{
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
BOOL bResult = GetSockName((SOCKADDR*)&sockAddr, &nSockAddrLen);
if (bResult)
{
rSocketPort = ntohs(sockAddr.sin_port);
rSocketAddress = inet_ntoa(sockAddr.sin_addr);
}
return bResult;
}
#endif //_AFX
BOOL CAsyncSocketEx::GetSockName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
{
if ( !getsockname(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen) )
return TRUE;
else
return FALSE;
}
BOOL CAsyncSocketEx::ShutDown( int nHow /*=sends*/ )
{
#ifndef NOLAYERS
if (m_pFirstLayer)
{
return m_pFirstLayer->ShutDown();
}
else
#endif //NOLAYERS
{
if ( !shutdown(m_SocketData.hSocket, nHow) )
return TRUE;
else
return FALSE;
}
}
SOCKET CAsyncSocketEx::Detach( )
{
SOCKET socket=m_SocketData.hSocket;
DetachHandle(socket);
m_SocketData.hSocket=INVALID_SOCKET;
return socket;
}
BOOL CAsyncSocketEx::Attach( SOCKET hSocket, long lEvent /*= FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/ )
{
if (hSocket==INVALID_SOCKET || !hSocket)
return FALSE;
VERIFY(InitAsyncSocketExInstance());
m_SocketData.hSocket=hSocket;
AttachHandle(hSocket);
#ifndef NOLAYERS
if (m_pFirstLayer)
{
m_lEvent = lEvent;
return !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
}
else
#endif //NOLAYERS
{
return AsyncSelect(lEvent);
}
}
BOOL CAsyncSocketEx::AsyncSelect( long lEvent /*= FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/ )
{
ASSERT(m_pLocalAsyncSocketExThreadData);
m_lEvent = lEvent;
#ifndef NOLAYERS
if (m_pFirstLayer)
return TRUE;
else
#endif //NOLAYERS
{
if ( !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, lEvent) )
return TRUE;
else
return FALSE;
}
return TRUE;
}
BOOL CAsyncSocketEx::Listen( int nConnectionBacklog /*=5*/ )
{
#ifndef NOLAYERS
if (m_pFirstLayer)
return m_pFirstLayer->Listen(nConnectionBacklog);
#endif //NOLAYERS
if (!listen(m_SocketData.hSocket, nConnectionBacklog))
{
#ifndef NOSOCKETSTATES
SetState(listening);
#endif //NOSOCKETSTATES
return TRUE;
}
else
return FALSE;
}
BOOL CAsyncSocketEx::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ )
{
ASSERT(rConnectedSocket.m_SocketData.hSocket == INVALID_SOCKET);
#ifndef NOLAYERS
if (m_pFirstLayer)
{
return m_pFirstLayer->Accept(rConnectedSocket, lpSockAddr, lpSockAddrLen);
}
else
#endif //NOLAYERS
{
SOCKET hTemp = accept(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen);
if (hTemp == INVALID_SOCKET)
return FALSE;
VERIFY(rConnectedSocket.InitAsyncSocketExInstance());
rConnectedSocket.m_SocketData.hSocket=hTemp;
rConnectedSocket.AttachHandle(hTemp);
#ifndef NOSOCKETSTATES
rConnectedSocket.SetState(connected);
#endif //NOSOCKETSTATES
}
return TRUE;
}
BOOL CAsyncSocketEx::IOCtl( long lCommand, DWORD* lpArgument )
{
return ioctlsocket(m_SocketData.hSocket, lCommand, lpArgument) != SOCKET_ERROR;
}
int CAsyncSocketEx::GetLastError()
{
return WSAGetLastError();
}
BOOL CAsyncSocketEx::TriggerEvent(long lEvent)
{
if (m_SocketData.hSocket==INVALID_SOCKET)
return FALSE;
ASSERT(m_pLocalAsyncSocketExThreadData);
ASSERT(m_pLocalAsyncSocketExThreadData->m_pHelperWindow);
ASSERT(m_SocketData.nSocketIndex!=-1);
#ifndef NOLAYERS
if (m_pFirstLayer)
{
CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg = new CAsyncSocketExLayer::t_LayerNotifyMsg;
pMsg->hSocket = m_SocketData.hSocket;
pMsg->lEvent=lEvent%0xFFFF;
pMsg->pLayer=0;
BOOL res=PostMessage(GetHelperWindowHandle(), WM_USER, (WPARAM)m_SocketData.nSocketIndex, (LPARAM)pMsg);
if (!res)
delete pMsg;
return res;
}
else
#endif //NOLAYERS
return PostMessage(GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, m_SocketData.hSocket, lEvent%0xFFFF);
}
SOCKET CAsyncSocketEx::GetSocketHandle()
{
return m_SocketData.hSocket;
}
HWND CAsyncSocketEx::GetHelperWindowHandle()
{
if (!m_pLocalAsyncSocketExThreadData)
return 0;
if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow)
return 0;
return m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd();
}
#ifndef NOLAYERS
BOOL CAsyncSocketEx::AddLayer(CAsyncSocketExLayer *pLayer)
{
ASSERT(pLayer);
if (m_pFirstLayer)
{
ASSERT(m_pLastLayer);
m_pLastLayer=m_pLastLayer->AddLayer(pLayer, this);
return m_pLastLayer?TRUE:FALSE;
}
else
{
ASSERT(!m_pLastLayer);
pLayer->Init(0, this);
m_pFirstLayer=pLayer;
m_pLastLayer=m_pFirstLayer;
if (m_SocketData.hSocket != INVALID_SOCKET)
if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
return FALSE;
}
return TRUE;
}
void CAsyncSocketEx::RemoveAllLayers()
{
m_pFirstLayer=0;
m_pLastLayer=0;
}
int CAsyncSocketEx::OnLayerCallback(const CAsyncSocketExLayer *pLayer, int nType, int nParam1, int nParam2)
{
ASSERT(pLayer);
return 1;
}
BOOL CAsyncSocketEx::IsLayerAttached() const
{
return m_pFirstLayer ? TRUE : FALSE;
}
#endif //NOLAYERS
BOOL CAsyncSocketEx::GetSockOpt(int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel /*=SOL_SOCKET*/)
{
return (SOCKET_ERROR != getsockopt(m_SocketData.hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, lpOptionLen));
}
BOOL CAsyncSocketEx::SetSockOpt(int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel /*=SOL_SOCKET*/)
{
return (SOCKET_ERROR != setsockopt(m_SocketData.hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, nOptionLen));
}
#ifndef NOSOCKETSTATES
int CAsyncSocketEx::GetState() const
{
return m_nState;
}
void CAsyncSocketEx::SetState(int nState)
{
m_nState=nState;
}
#endif //NOSOCKETSTATES
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?