📄 asyncsocketex.cpp
字号:
}
delete pMsg;
return 0;
}
#endif //NOLAYERS
else if (message == WM_SOCKETEX_GETHOST)
{
//WSAAsyncGetHostByName reply
//Verify parameters
ASSERT(hWnd);
CAsyncSocketExHelperWindow *pWnd=(CAsyncSocketExHelperWindow *)GetWindowLong(hWnd, GWL_USERDATA);
ASSERT(pWnd);
CAsyncSocketEx *pSocket = NULL;
for (int i=0; i<pWnd->m_nWindowDataSize; i++)
{
pSocket = pWnd->m_pAsyncSocketExWindowData[i].m_pSocket;
if (pSocket && pSocket->m_hAsyncGetHostByNameHandle &&
pSocket->m_hAsyncGetHostByNameHandle == (HANDLE)wParam)
break;
}
if (i == pWnd->m_nWindowDataSize)
return 0;
int nErrorCode = lParam >> 16;
if (nErrorCode)
{
pSocket->OnConnect(nErrorCode);
return 0;
}
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
sockAddr.sin_family=AF_INET;
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)((LPHOSTENT)pSocket->m_pAsyncGetHostByNameBuffer)->h_addr)->s_addr;
sockAddr.sin_port = htons(pSocket->m_nAsyncGetHostByNamePort);
BOOL res = pSocket->Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
delete [] pSocket->m_pAsyncGetHostByNameBuffer;
pSocket->m_pAsyncGetHostByNameBuffer=0;
pSocket->m_hAsyncGetHostByNameHandle=0;
if (!res)
if (GetLastError()!=WSAEWOULDBLOCK)
pSocket->OnConnect(GetLastError());
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
#ifdef USE_CLIENT_TCP_CATCH_ALL_HANDLER
}
catch(CException* e){
TCHAR szError[1024];
e->GetErrorMessage(szError, ARRSIZE(szError));
const CRuntimeClass* pRuntimeClass = e->GetRuntimeClass();
LPCSTR pszClassName = (pRuntimeClass) ? pRuntimeClass->m_lpszClassName : NULL;
if (!pszClassName)
pszClassName = "CException";
TRACE(_T("*** Unknown %hs exception in CAsyncSocketExHelperWindow::WindowProc - %s\n"), pszClassName, szError);
e->Delete();
}
catch (...) {
// TODO: This exception handler should definitively *not* be here. Though we seem to need it to
// catch some very strange crashs which deal with socket deletion problems in the client's TCP socket.
TRACE("*** Unknown exception in CAsyncSocketExHelperWindow::WindowProc\n");
ASSERT(0);
}
#endif
return 0;
}
HWND CAsyncSocketExHelperWindow::GetHwnd()
{
return m_hWnd;
}
private:
HWND m_hWnd;
struct t_AsyncSocketExWindowData
{
CAsyncSocketEx *m_pSocket;
} *m_pAsyncSocketExWindowData;
int m_nWindowDataSize;
int m_nWindowDataPos;
int m_nSocketCount;
};
//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CAsyncSocketEx, CObject)
CAsyncSocketEx::CAsyncSocketEx()
{
m_SocketData.hSocket=INVALID_SOCKET;
m_SocketData.nSocketIndex=-1;
m_pLocalAsyncSocketExThreadData=0;
#ifndef NOLAYERS
m_pFirstLayer=0;
m_pLastLayer=0;
#endif //NOLAYERS
m_pAsyncGetHostByNameBuffer = NULL;
m_hAsyncGetHostByNameHandle = NULL;
}
CAsyncSocketEx::~CAsyncSocketEx()
{
Close();
FreeAsyncSocketExInstance();
}
BOOL CAsyncSocketEx::Create( UINT nSocketPort /*=0*/, int nSocketType /*=SOCK_STREAM*/, long lEvent /*=FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/, LPCTSTR lpszSocketAddress /*=NULL*/, BOOL bReuseAddr /*=FALSE*/ )
{
ASSERT(GetSocketHandle()==INVALID_SOCKET);
//Close the socket, although this should not happen
if (GetSocketHandle() != INVALID_SOCKET)
{
WSASetLastError(WSAEALREADY);
return FALSE;
}
BOOL res=InitAsyncSocketExInstance();
ASSERT(res);
if (!res)
{
WSASetLastError(WSANOTINITIALISED);
return FALSE;
}
#ifndef NOLAYERS
if (m_pFirstLayer)
return m_pFirstLayer->Create(nSocketPort, nSocketType, lEvent, lpszSocketAddress);
else
#endif //NOLAYERS
{
SOCKET hSocket=socket(AF_INET, nSocketType, 0);
if (hSocket==INVALID_SOCKET)
return FALSE;
m_SocketData.hSocket=hSocket;
AttachHandle(hSocket);
if (!AsyncSelect(lEvent))
{
Close();
return FALSE;
}
#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) )
{
Close();
return FALSE;
}
}
#endif //NOLAYERS
if (bReuseAddr)
{
// Has to be done right before binding the socket!
int iOptVal = 1;
VERIFY( SetSockOpt(SO_REUSEADDR, &iOptVal, sizeof iOptVal) );
}
if (!Bind(nSocketPort, lpszSocketAddress))
{
Close();
return FALSE;
}
return TRUE;
}
}
void CAsyncSocketEx::OnReceive(int nErrorCode)
{
}
void CAsyncSocketEx::OnSend(int nErrorCode)
{
}
void CAsyncSocketEx::OnConnect(int nErrorCode)
{
}
void CAsyncSocketEx::OnAccept(int nErrorCode)
{
}
void CAsyncSocketEx::OnClose(int nErrorCode)
{
}
BOOL CAsyncSocketEx::Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress)
{
USES_CONVERSION;
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
LPSTR lpszAscii = T2A((LPTSTR)lpszSocketAddress);
sockAddr.sin_family = AF_INET;
if (lpszAscii == NULL)
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
else
{
DWORD lResult = inet_addr(lpszAscii);
if (lResult == INADDR_NONE)
{
WSASetLastError(WSAEINVAL);
return FALSE;
}
sockAddr.sin_addr.s_addr = lResult;
}
sockAddr.sin_port = htons((u_short)nSocketPort);
return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
}
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));
}
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));
}
void CAsyncSocketEx::Close()
{
#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;
}
#ifndef NOLAYERS
RemoveAllLayers();
#endif //NOLAYERS
delete [] m_pAsyncGetHostByNameBuffer;
m_pAsyncGetHostByNameBuffer = NULL;
if (m_hAsyncGetHostByNameHandle)
WSACancelAsyncRequest(m_hAsyncGetHostByNameHandle);
m_hAsyncGetHostByNameHandle = NULL;
}
BOOL CAsyncSocketEx::InitAsyncSocketExInstance()
{
//Check if already initialized
if (m_pLocalAsyncSocketExThreadData)
return TRUE;
DWORD id=GetCurrentThreadId();
BOOL bResult = TRUE;
m_sGlobalCriticalSection.Lock();
try{
//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;
}
}
catch(...){
TRACE("Unknown exception in CAsyncSocketEx::InitAsyncSocketExInstance()\n");
ASSERT(0);
bResult = FALSE;
}
m_sGlobalCriticalSection.Unlock();
return bResult;
}
void CAsyncSocketEx::FreeAsyncSocketExInstance()
{
//Check if already freed
if (!m_pLocalAsyncSocketExThreadData)
return;
DWORD id=m_pLocalAsyncSocketExThreadData->nThreadId;
m_sGlobalCriticalSection.Lock();
try{
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -