⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asyncsocketex.cpp

📁 一个支持FTP,SFTP的客户端程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		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 + -