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 + -
显示快捷键?