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

📄 tcpip.cpp

📁 这个是应用了很多工程的TCPIP通讯库
💻 CPP
📖 第 1 页 / 共 5 页
字号:
											   OUT TCHAR *szSORcvBuf,  IN OUT int *dpSORcvBufSize,
											   OUT int *dpLastError)
{
	DWORD dwErrorCode = IO_SUCCESS;
	int nError;

	// This is a client not server. Just go away.
	if (!this->m_bClient)
	{
		dwErrorCode = IO_CLIENT_ERR;
		return(dwErrorCode);
	}

	//
	//	If Socket not created or already closed; then just return
	//	If you add any other states then you may want to change this.
	//
	if (this->m_bSocketState != SOCKET_CREATED)
	{
		dwErrorCode = IO_SOCKET_ERROR;
		return(dwErrorCode);
	}

	//
	//	Get socket options on this socket 
	//
	if (((nError = getsockopt (this->m_Socket, SOL_SOCKET, SO_SNDBUF,   (char *) szSOSendBuf, (int *)dpSOSendBufSize )) == SOCKET_ERROR) ||
		((nError = getsockopt (this->m_Socket, SOL_SOCKET, SO_RCVBUF,   (char *) szSORcvBuf,  (int *)dpSORcvBufSize )) == SOCKET_ERROR) )
	{
		//
		//  Unable to get the socket options
		//
		 *dpLastError = WSAGetLastError();
		dwErrorCode = IO_SOCKET_OPTION_ERROR;
	}
	return(dwErrorCode);
}


//
// @mfunc   GetSocketTmoOptions -  In Tcp/Udp Client Mode
//			This function gets the common socket Timeout options
//
// @parm   OUT TCHAR * | szRcvTmo | Receive Buffer Timeout period
//
// @parm   IN OUT int * | dpRcvTmoSize | Sizeof szRcvTmo 
//
// @parm   OUT TCHAR * | szSendTmo | Send Buffer Timeout period
//
// @parm   IN OUT int * | dpSendTmoSize | Sizeof szSendTmo
//
// @parm   OUT int * | dpLastError | Last Error Number
//
// @rvalue IO_SUCCESS | If successful
//
// @rvalue IO_SOCKET_OPTION_ERROR | If fails
//
// @rvalue IO_CLIENT_ERR | If object not in client mode
//
// @rvalue IO_SOCKET_ERROR | If Client Socket Invalid
//
EXPORT32 DWORD CTcpIp::GetSocketTmoOptions (OUT TCHAR *szRcvTmo,  IN OUT int *dpRcvTmoSize,
											OUT TCHAR *szSendTmo, IN OUT int *dpSendTmoSize,
											OUT int *dpLastError)
{
	DWORD dwErrorCode = IO_SUCCESS;
	int nError;

	// This is a client not server. Just go away.
	if (!this->m_bClient)
	{
		dwErrorCode = IO_CLIENT_ERR;
		return(dwErrorCode);
	}

	//
	//	If Socket not created or already closed; then just return
	//	If you add any other states then you may want to change this.
	//
	if (this->m_bSocketState != SOCKET_CREATED)
	{
		dwErrorCode = IO_SOCKET_ERROR;
		return(dwErrorCode);
	}

	//
	//	Get socket options on this socket 
	//
	if (((nError = getsockopt (this->m_Socket, SOL_SOCKET, SO_RCVTIMEO, (char *) szRcvTmo, (int *)dpRcvTmoSize)) == SOCKET_ERROR) ||
		((nError = getsockopt (this->m_Socket, SOL_SOCKET, SO_SNDTIMEO, (char *) szSendTmo,(int *)dpSendTmoSize)) == SOCKET_ERROR)) 
	{
		//
		//  Unable to get the socket options
		//
		 *dpLastError = WSAGetLastError();
		dwErrorCode = IO_SOCKET_OPTION_ERROR;
	}

	return(dwErrorCode);
}

//
// @mfunc   GetConnectState -  In Tcp/Udp Client Mode
//			This function gets the Connection State of the object
//
// @parm   void
//
// @rvalue DRV_CONNECTED | If object currently connected
//
// @rvalue DRV_CONNECTING | If connection still in progress
//
// @rvalue DRV_CONNECT_FAILED | If connection failed
//
// @rvalue DRV_NOT_CONNECTED | If not connected
//
EXPORT32 DWORD CTcpIp::GetConnectState(void)
{
	return(this->m_dwConnectState);
}


//
// Function: GetAddr()
//
// Description: Given a string, it will return an IP address.
//   - first it tries to convert the string directly
//   - if that fails, it tries to resolve it as a hostname
//
// WARNING: gethostbyname() is a blocking function
//
unsigned long CTcpIp::GetAddr(IN const TCHAR *szHost)
{
  LPHOSTENT lpstHost;
  unsigned long lAddr = INADDR_ANY;
  
  // check that we have a string 
  if (*szHost)
  {
  
    // check for a dotted-IP address string
    lAddr = inet_addr (szHost);
  
	// If not an address, then try to resolve it as a hostname
    if ((lAddr == INADDR_NONE) &&
        (strcmp (szHost, "255.255.255.255")))
	{
      
		lpstHost = gethostbyname(szHost);
		if (lpstHost) 
		{
			lAddr = *((unsigned long *)(lpstHost->h_addr));
		}
		else 
		{  
	        lAddr = INADDR_NONE;
		}
    }
  }
  return (lAddr); 
}

//
//
// FUNCTION:	ReportConnectError
//
// Description: Displays a connection message if successfully connected
//				or displays a error message if connect fails.
//
//
void CTcpIp::ReportConnectError(IN TCHAR *szMsg, IN BOOL bSuccess)
{
	TCHAR szErrorMsg[256];

	if (bSuccess)
	{
		sprintf(szErrorMsg, "Successfully connected to %s port %u",
			    this->m_szIpAddress, this->m_uPortNumber);
		TRACE("TCP: Successfully connected to %s port %u",this->m_szIpAddress, this->m_uPortNumber);
	}
	else
	{
		sprintf(szErrorMsg, "Error connecting to %s port %u:  %s",
			    this->m_szIpAddress, this->m_uPortNumber, szMsg);
		TRACE("TCP: Error connecting to %s port %u",this->m_szIpAddress, this->m_uPortNumber);
	}

	DisplayMessage(szErrorMsg);

}


//
//
//	FUNCTION:	(LPTHREAD_START_ROUTINE)ListenHandler
//
//	This function is the start address for the 
//	listen thread
//
BOOL CTcpIp::ListenHandler(IN LPVOID ptr)
{
	CTcpIp	*pObj = (CTcpIp *)ptr;

	if (pObj == NULL)
	{
		ExitThread(FALSE);
		return(FALSE);
	}

	// This is a client not server. Just go away.
	if (pObj->m_bClient)
	{
		ExitThread(FALSE);
		return(FALSE);
	}

	DWORD dwErrorCode = IO_SUCCESS;

	if (pObj->m_Socket != INVALID_SOCKET)
	{
		dwErrorCode = IO_CREATE_SOCKET;
		pObj->m_bSocketState = SOCKET_CLOSED;
		pObj->m_Socket = INVALID_SOCKET;
		TRACE("TCP: Failed to create a new socket\n");
	}

	int				nError = 0;
	int				nLastError = 0;

	unsigned long	uNonBlock = 1;
	struct sockaddr_in	sClientSockAddress;
	SOCKET NewSocket;
	
	//
	// Create a Listen Socket. By default it is in Blocking Mode
	//
	if (pObj->m_bTcp)
	{
		pObj->m_Socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
	}
	else
	{
		pObj->m_Socket = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED);
	}

    if (INVALID_SOCKET == pObj->m_Socket)
	{
		nLastError = WSAGetLastError();
		dwErrorCode = IO_CREATE_SOCKET;
		pObj->m_bSocketState = SOCKET_CLOSED;
		pObj->m_Socket = INVALID_SOCKET;
		TRACE("TCP: Open- WSASocket() failed to create a new socket, Error = %d\n",WSAGetLastError());
		ExitThread(nLastError);
		return(FALSE);
	}
	else
	{
		int	opt_val = 1,
			nError,
			nTxBufSize = TCP_INPUT_QUEUE_SIZE,
			nRxBufSize = TCP_OUTPUT_QUEUE_SIZE;

		nError = setsockopt(pObj->m_Socket, SOL_SOCKET, SO_DONTLINGER, (char *)&opt_val, sizeof(opt_val));

		if (pObj->m_bTcp)
		{
			nError = setsockopt(pObj->m_Socket, IPPROTO_TCP, TCP_NODELAY, (char *)&opt_val, sizeof(opt_val));
		}

		pObj->m_bSocketState = SOCKET_CREATED;
		TRACE("TCP: New socket created\n");
	}

	
	//
	//	Set to non-blocking mode
	//
	nError = ioctlsocket(pObj->m_Socket, FIONBIO, &uNonBlock);
	if (SOCKET_ERROR == nError)
	{	
		pObj->m_dwConnectState = DRV_SOCKET_ERROR;
	}
	else
	{
		pObj->m_dwConnectState = DRV_SOCKET_NONBLOCKING;
	}


	pObj->m_sSocketAddress.sin_family           = AF_INET;
	pObj->m_sSocketAddress.sin_addr.s_addr		= INADDR_ANY;
	pObj->m_sSocketAddress.sin_port             = (unsigned short) htons(pObj->m_uPortNumber);

	//
	//	Bind the socket to the local name and ipaddress 
	//
	nError = bind(pObj->m_Socket, (LPSOCKADDR) &(pObj->m_sSocketAddress), sizeof(sockaddr_in));

	if (SOCKET_ERROR == nError)
	{	
		nLastError = WSAGetLastError();
		pObj->m_dwConnectState = DRV_SOCKET_ERROR;
		pObj->m_bSocketState = SOCKET_CLOSING;
		pObj->CloseAllConnections();
		ExitThread(nLastError);
		return(FALSE);
	}

	if (!pObj->m_bTcp)
	{
	//
	//	For Udp, start the receive handler
	//
		if (!pObj->m_bStop)
		{

			pObj->m_hReceiveThread	= CreateThread(NULL,
									0,
									(LPTHREAD_START_ROUTINE)ReceiveUdpHandler,
									(LPVOID)ptr, 
									0, 
									&pObj->m_dwReceiveThreadId);
		}
		else
		{
			if (pObj->m_Socket != INVALID_SOCKET)
			{
				//
				//  Close the socket
				//
				nError = closesocket(pObj->m_Socket);
				pObj->m_Socket = INVALID_SOCKET;
			}
			pObj->m_dwConnectState = DRV_SOCKET_ERROR;
			ExitThread(nLastError);
			return(FALSE);
		}// End of else loop

	}
	else
	{
		//
		//	For Tcp
		//	Listen for connection. 
		//
		nError = listen(pObj->m_Socket, MAX_LISTEN_QUEUE);
		if (SOCKET_ERROR == nError)
		{	
			nLastError = WSAGetLastError();
			if (pObj->m_Socket != INVALID_SOCKET)
			{
				//
				//  Close the socket
				//
				nError = closesocket(pObj->m_Socket);
				pObj->m_Socket = INVALID_SOCKET;
			}
			pObj->m_dwConnectState = DRV_SOCKET_ERROR;
			ExitThread(nLastError);
			return(FALSE);
		}

		CONNECION_DATA *pConnectionInfo = NULL;
	//	int nMaxEntries = 0;
		int	nTotalEntries = 0;;
		int nLength = sizeof(sockaddr);
		BOOL bFirstTimeFlag = TRUE;
		DWORD dwTimeStart = 0L, dwTimeCurrent = 0L, dwTimeDiff = 0L;

		dwTimeStart = GetTickCount();

		SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
		SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);

		while (!pObj->m_bStop)
		{
#ifdef _DEBUG
			if (bFirstTimeFlag)
			{
				TRACE("TCP: Server : In accept connection loop. Timer = %ld \n", dwTimeStart);
				bFirstTimeFlag = FALSE;
			}
			else
			{
				dwTimeCurrent = GetTickCount();
				dwTimeDiff = dwTimeCurrent - dwTimeStart;

				// if time difference > 60secs. display message in trace window
				if (dwTimeDiff > (DWORD)60000L)
				{
					TRACE("TCP: Server : Timer Up. In accept connection loop. %ld\n", dwTimeCurrent);
					dwTimeStart = dwTimeCurrent;
				}
	
			}// end else loop
#endif // _DEBUG

			pObj->m_bSocketState = SOCKET_ACCEPTING;

			if ((NewSocket = accept(pObj->m_Socket, (LPSOCKADDR)&sClientSockAddress, &nLength))
							== INVALID_SOCKET)
			{
				nLastError = WSAGetLastError();

				switch (nLastError)
				{
				//	A successful WSAStartup must occour
				case WSANOTINITIALISED	:	

				//	The network subsystem has failed
				case WSAENETDOWN		:

				//	The addrlen parameter is too small or addr is not a valid part of 
				//	the user address space
				case WSAEFAULT			:	

				//	The listen function was not invoked prior to accept.
				case WSAEINVAL			:	

				//	The descriptor is not a socket.
				case WSAENOTSOCK		:	

				//	The referenced socket is not a type that supports 
				//	connection-oriented service.
				case WSAEOPNOTSUPP		:	

				//	A blocking Windows Sockets call was canceled through 
				//	WSACancelBlockingCall
				case WSAEINTR	:

				//	No buffer space is available.
				case WSAENOBUFS	:

				//	The queue is nonempty upon entry to accept and 
				//	there are no descriptors available.
				case WSAEMFILE	:
							pObj->m_bSocketState = DRV_ACCEPT_ERROR;
					break;

				//	A blocking Windows Sockets call is in progress, 
				//	or the service provider is still processing a callback function.
				case WSAEINPROGRESS	:
					break;

			
				//	The socket is marked as nonblocking and 
				//	no connections are present to be accepted.
				case WSAEWOULDBLOCK	:
					break;

				//	default. return value unknown. 
				//	just go on.
				default:
					break;

				}//	End of switch statement

				if (pObj->m_bSocketState == DRV_ACCEPT_ERROR)
				{
					// Error occoured. break out of while loop. Cleanup and shutdown
					TRACE("TCP: Server Failed to accept connection. WSALastError = %d \n", nLastError);
					break;
				}
				else
				{
					// Continue to accept connections.
					pObj->m_bSocketState = SOCKET_ACCEPTING;
					//	sleep for a small period before looping back
					Sleep(SERVER_ACPT_TIMEOUT);

⌨️ 快捷键说明

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