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

📄 te_socket.cpp

📁 类似于flashget的下载软件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	}

	// 注册FD_CONNECT事件
	if( WSAEventSelect(hSocket, (WSAEVENT) hConnectEvent, FD_CONNECT) == SOCKET_ERROR)
	{
		CloseHandle(hConnectEvent);
		TE_SetLastError( WSAGetLastError() );
		return (SOCKET_ERROR);
	}

	int	iConnectResult = WSAConnect(hSocket, pSocketAddress, iNameLen, NULL, NULL, NULL, NULL);
	int	iConnectError  = WSAGetLastError();
	
	if ((iConnectResult == SOCKET_ERROR) && (iConnectError == WSAEWOULDBLOCK))
	{
		DWORD dwWaitResult = WSAWaitForMultipleEvents(1, &hConnectEvent, TRUE,dwTimeout, TRUE);
		
		if (dwWaitResult != WSA_WAIT_EVENT_0)
		{
			TE_SetLastError( WSAGetLastError() );
			iConnectResult = SOCKET_ERROR;
		}
		else
		{
			////////////////////////////////////////////////////////////// 
			///	注意:即使 dwWaitResult == WSA_WAIT_EVENT0 ,也应该 
			///			进一步检查网络是否发生错误
			///////////////////////////////////////////////////////////////
			WSANETWORKEVENTS NetEvent;
			if(WSAEnumNetworkEvents(hSocket,(WSAEVENT)hConnectEvent,&NetEvent) == SOCKET_ERROR)
			{
				TE_SetLastError( WSAGetLastError() );
				iConnectResult = SOCKET_ERROR;
			}
			else if(NetEvent.iErrorCode[FD_CONNECT_BIT] !=0 )	// 发生错误
			{
				TE_SetLastError( NetEvent.iErrorCode[FD_CONNECT_BIT] );
				iConnectResult = SOCKET_ERROR;
			}
			else
				iConnectResult = SOCKET_SUCCESS;
			////////////////////////////////////////////////////////////////
		}
	}

	// 注销网络事件
	WSAEventSelect(hSocket, (WSAEVENT) hConnectEvent, 0);
	CloseHandle(hConnectEvent);
	return (iConnectResult);
}


///////////////////////////////////////////////////////////
//
//	引入该函数的目的是为了避免NT下对域名解析的CACHE造成的问题
//
///////////////////////////////////////////////////////////
DWORD WINAPI DNSThread(  LPVOID pParam )
{
	DWORD dwIP = INADDR_NONE;
	PHOSTENT pHost = gethostbyname( (char *)pParam );
	if(pHost == NULL)
		return INADDR_NONE;
	dwIP = inet_addr( inet_ntoa(*(IN_ADDR *)*pHost->h_addr_list) );
	return dwIP;
}

DWORD TE_GetIP(const char* name,BOOL fFixNtDNS /* = FALSE*/) // Used to Fix NT DNS Problem
{
	DWORD dwIP = inet_addr(name);
	if( dwIP != INADDR_NONE )
		return dwIP;

	if( fFixNtDNS )
	{
		OSVERSIONINFO		osVersion;
		osVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
		if( GetVersionEx(&osVersion) )
		{
			if(osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT)
			{
				DWORD	dwThreadId = 0;
				HANDLE	hThread = CreateThread(NULL,0,DNSThread,(LPVOID)name,0,&dwThreadId);
				if( hThread != NULL)
				{
					WaitForSingleObject(hThread,INFINITE);
					if( GetExitCodeThread(hThread,&dwIP))
						return dwIP;
				}
			}
		}
	}

	PHOSTENT pHost = gethostbyname(name);
	if(pHost == NULL)
		return INADDR_NONE;
		
	dwIP = inet_addr( inet_ntoa(*(IN_ADDR *)*pHost->h_addr_list) );
	return dwIP;
}

// 建立连接(扩展函数)
int TE_ConnectEx(SOCKET hSocket, char const * pszServer, int nPort,DWORD dwTimeout,BOOL fFixNtDNS /*= FALSE*/)
{
	/////////////////////////////////////////////////////////////////////////////
	SOCKADDR_IN sockAddr;
	ZeroMemory(&sockAddr,sizeof(sockAddr));

	sockAddr.sin_family			= AF_INET;
	sockAddr.sin_port			= htons((u_short)nPort);
	sockAddr.sin_addr.s_addr	= TE_GetIP(pszServer,fFixNtDNS);
	
	if (sockAddr.sin_addr.s_addr == INADDR_NONE)
	{
		TE_SetLastError( WSAGetLastError() );
		return (SOCKET_ERROR);
	}
	//////////////////////////////////////////////////////////////////////

	return TE_Connect(hSocket, (SOCKADDR *)&sockAddr,sizeof(sockAddr),dwTimeout);
}
// 绑定套接字
int TE_BindSocket(SOCKET hSocket, const struct sockaddr * SockName, int iNameLen)
{

	if (bind(hSocket, SockName, iNameLen) == SOCKET_ERROR)
	{
		TE_SetLastError( WSAGetLastError() );
		return (SOCKET_ERROR);
	}

	return (SOCKET_SUCCESS);
}

// 绑定套接字
int TE_BindSocketEx(SOCKET hSocket,int nPort)
{
	SOCKADDR_IN sockAddr;
	ZeroMemory(&sockAddr,sizeof(sockAddr));

	sockAddr.sin_family			= AF_INET;
	sockAddr.sin_addr.s_addr	= htonl(INADDR_ANY);
	sockAddr.sin_port			= htons((u_short)nPort);

	return TE_BindSocket(hSocket,(SOCKADDR *)&sockAddr, sizeof(sockAddr));
}


// 监听套接字
int TE_ListenSocket(SOCKET hSocket, int iConnections)
{
	if(listen(hSocket, iConnections) == SOCKET_ERROR)
	{
		TE_SetLastError( WSAGetLastError() );
		return (SOCKET_ERROR);
	}
	
	return (SOCKET_SUCCESS);
}


// 接受套接字连接
SOCKET TE_Accept(SOCKET hSocket, struct sockaddr * pSocketAddress, int *iNameLen,DWORD dwTimeout)
{

	HANDLE hAcceptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (hAcceptEvent == NULL)
	{
		TE_SetLastError( (int)GetLastError() );
		return (INVALID_SOCKET);
	}

	// 注册FD_ACCEPT事件
	if( WSAEventSelect(hSocket, (WSAEVENT) hAcceptEvent, FD_ACCEPT) == SOCKET_ERROR)
	{
		CloseHandle(hAcceptEvent);
		TE_SetLastError( WSAGetLastError() );
		return (INVALID_SOCKET);
	}

	SOCKET hSocketAccept = WSAAccept(hSocket, pSocketAddress, iNameLen, NULL, 0);
	int	   iConnectError = WSAGetLastError();

	if ((hSocketAccept == INVALID_SOCKET) && (iConnectError == WSAEWOULDBLOCK))
	{

		// 阻塞
		DWORD dwWaitResult = WSAWaitForMultipleEvents(1, &hAcceptEvent, TRUE,dwTimeout, TRUE);

		if (dwWaitResult == WSA_WAIT_EVENT_0)
		{
			////////////////////////////////////////////////////////////// 
			///	注意:即使 dwWaitResult == WSA_WAIT_EVENT0 ,也应该 
			///			进一步检查网络是否发生错误
			///////////////////////////////////////////////////////////////
			WSANETWORKEVENTS NetEvent;
			if(WSAEnumNetworkEvents(hSocket,hAcceptEvent,&NetEvent) == SOCKET_ERROR)
				TE_SetLastError( WSAGetLastError() );
			else if(NetEvent.iErrorCode[FD_ACCEPT_BIT] !=0 )	// 发生错误
				TE_SetLastError( NetEvent.iErrorCode[FD_ACCEPT_BIT] );
			else
				hSocketAccept = WSAAccept(hSocket, pSocketAddress, iNameLen, NULL, 0);
		}
		else
			TE_SetLastError( WSAGetLastError() );
	}
	
	// 注销网络事件
	WSAEventSelect(hSocket, (WSAEVENT) hAcceptEvent, 0);
	CloseHandle(hAcceptEvent);

	if (hSocketAccept != INVALID_SOCKET)
	{
		// 设置套接字的属性为地址可重用并且为非阻塞的
		if (	(TE_BlockSocket(hSocketAccept, 0)  == SOCKET_ERROR ) ||
				(TE_SetSocketOption(hSocketAccept) == SOCKET_ERROR ) )
		{
			TE_CloseSocket(hSocketAccept,TRUE);
			return (INVALID_SOCKET);
		}
	}
	return (hSocketAccept);
}

// 接受套接字连接(允许中断)
SOCKET	TE_AcceptEx(SOCKET hSocket, struct sockaddr * pSockName, int *iNameLen,HANDLE hEndEvent,DWORD dwTimeout /*= TE_DEFAULT_TIMEOUT*/)
{
	if( hEndEvent == NULL)
		return TE_Accept(hSocket,pSockName,iNameLen,dwTimeout);

	HANDLE	hAcceptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (hAcceptEvent == NULL)
	{
		TE_SetLastError( (int)GetLastError() );
		return (INVALID_SOCKET);
	}

	WSAEVENT hEvent[2]; 
	hEvent[0] = (WSAEVENT)hAcceptEvent;
	hEvent[1] = (WSAEVENT)hEndEvent;

	// 注册FD_ACCEPT事件
	if( WSAEventSelect(hSocket, (WSAEVENT) hAcceptEvent, FD_ACCEPT) == SOCKET_ERROR)
	{
		CloseHandle(hAcceptEvent);
		TE_SetLastError( WSAGetLastError() );
		return (INVALID_SOCKET);
	}

	SOCKET hSocketAccept = WSAAccept(hSocket, pSockName, iNameLen, NULL, 0);
	int	   iConnectError = WSAGetLastError();

	if ((hSocketAccept == INVALID_SOCKET) && (iConnectError == WSAEWOULDBLOCK))
	{
		// 阻塞
		DWORD dwWaitResult = WSAWaitForMultipleEvents(2, hEvent, FALSE,dwTimeout, TRUE);
		if (dwWaitResult == WSA_WAIT_EVENT_0)
		{
			////////////////////////////////////////////////////////////// 
			///	注意:即使 dwWaitResult == WSA_WAIT_EVENT0 ,也应该 
			///			进一步检查网络是否发生错误
			///////////////////////////////////////////////////////////////
			WSANETWORKEVENTS NetEvent;
			if(WSAEnumNetworkEvents(hSocket,hAcceptEvent,&NetEvent) == SOCKET_ERROR)
				TE_SetLastError( WSAGetLastError() );
			else if(NetEvent.iErrorCode[FD_ACCEPT_BIT] !=0 )	// 发生错误
				TE_SetLastError( NetEvent.iErrorCode[FD_ACCEPT_BIT] );
			else
				hSocketAccept = WSAAccept(hSocket, pSockName, iNameLen, NULL, 0);
		}
		else
			TE_SetLastError( WSAGetLastError() );
	}
	
	// 注销网络事件
	WSAEventSelect(hSocket, (WSAEVENT) hAcceptEvent, 0);
	CloseHandle(hAcceptEvent);

	if (hSocketAccept != INVALID_SOCKET)
	{
		// 设置套接字的属性为地址可重用并且为非阻塞的
		if (	(TE_BlockSocket(hSocketAccept, 0) < 0) ||
				(TE_SetSocketOption(hSocketAccept) < 0) )
		{
			TE_CloseSocket(hSocketAccept,TRUE);
			return (INVALID_SOCKET);
	
		}
	}
	return (hSocketAccept);

}

// 设置套接字是否为阻塞的
int      TE_BlockSocket(SOCKET hSocket, BOOL bBlock)
{
	u_long  IoctlLong = (bBlock) ? 0 : 1;

	if (ioctlsocket(hSocket, FIONBIO, &IoctlLong) == SOCKET_ERROR)
	{
		TE_SetLastError( WSAGetLastError() );
		return (SOCKET_ERROR);
    }

	return (SOCKET_SUCCESS);

}

// 数据报接收函数
int TE_RecvDataFrom( SOCKET hSocket, struct sockaddr * pFrom, int iFromlen,
					 char *pszBuffer, int iBufferSize, DWORD dwTimeout)
{
	HANDLE hReadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (hReadEvent == NULL)
	{
		TE_SetLastError((int)GetLastError() );
		return (SOCKET_ERROR);
	}

	DWORD		dwRtxBytes = 0,
				dwRtxFlags = 0;
	WSABUF		WSABuff;

	ZeroMemory(&WSABuff,sizeof(WSABUF));
	WSABuff.len = iBufferSize;
	WSABuff.buf = pszBuffer;

	for (;;)
	{
		// 注册FD_READ事件
		if( WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, FD_READ) == SOCKET_ERROR)
		{
			CloseHandle(hReadEvent);
			TE_SetLastError(  WSAGetLastError() );
			return (SOCKET_ERROR);
		}
		DWORD dwWaitResult = WSAWaitForMultipleEvents(1, &hReadEvent, TRUE,	dwTimeout, TRUE);

		if( dwWaitResult != WSA_WAIT_EVENT_0 )
		{
			// 注销事件
			WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, 0);
			CloseHandle(hReadEvent);
			TE_SetLastError( WSAGetLastError());
			return (SOCKET_ERROR);
		}

		////////////////////////////////////////////////////////////// 
		///	注意:即使 dwWaitResult == WSA_WAIT_EVENT0 ,也应该 
		///			进一步检查网络是否发生错误
		///////////////////////////////////////////////////////////////
		WSANETWORKEVENTS NetEvent;
		if(WSAEnumNetworkEvents(hSocket,(WSAEVENT)hReadEvent,&NetEvent) == SOCKET_ERROR)
		{
			// 注销事件
			WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, 0);
			CloseHandle(hReadEvent);
			TE_SetLastError( WSAGetLastError() );
			return (SOCKET_ERROR);
		}
		if(NetEvent.iErrorCode[FD_READ_BIT] !=0 )	// 发生错误
		{
			// 注销事件
			WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, 0);
			CloseHandle(hReadEvent);
			TE_SetLastError(NetEvent.iErrorCode[FD_READ_BIT]);
			return (SOCKET_ERROR);
		}
		////////////////////////////////////////////////////////////////
		// 注销事件
		WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, 0);

		int FromLen = iFromlen;
		if ( WSARecvFrom(hSocket, &WSABuff, 1, &dwRtxBytes, &dwRtxFlags,pFrom, &FromLen, NULL, NULL) == SOCKET_SUCCESS )
			break;

		if ( WSAGetLastError() != WSAEWOULDBLOCK)
		{
			CloseHandle(hReadEvent);
			TE_SetLastError( WSAGetLastError() );
			return (SOCKET_ERROR);
		}

		///////////////////////////////////////////////////////////////////////////
		//	睡眠一段时间
		//////////////////////////////////////////////////////////////////////////
		Sleep(TE_BLOCKED_SNDRCV_SLEEP);
	}
	CloseHandle(hReadEvent);
	return ((int) dwRtxBytes);
}

// 数据报发送数据报
int TE_SendDataTo(SOCKET hSocket, const struct sockaddr * pTo,int iToLen,
				  char const * pszBuffer, int iBufferSize, DWORD dwTimeout)
{
	HANDLE hWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (hWriteEvent == NULL)
	{
		TE_SetLastError( (int)GetLastError() );
		return (SOCKET_ERROR);
	}

	DWORD	dwRtxBytes = 0,
            dwRtxFlags = 0;
	WSABUF	WSABuff;

	ZeroMemory(&WSABuff,sizeof(WSABUF));
	WSABuff.len = iBufferSize;
	WSABuff.buf = (char *) pszBuffer;

	for (;;)
	{
		if (WSASendTo( hSocket, &WSABuff, 1, &dwRtxBytes, dwRtxFlags,pTo, iToLen, NULL, NULL) == SOCKET_SUCCESS)
			break;

		if (WSAGetLastError() != WSAEWOULDBLOCK)
		{
			CloseHandle(hWriteEvent);
			TE_SetLastError(  WSAGetLastError() );
			return (SOCKET_ERROR);
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -