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

📄 tcpsocket.cpp

📁 网络聊天工具原代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	int		i;
	BOOL	bIP;
	int		nNumber;  
	struct	hostent *ip;
	DWORD	dwIP;
	char	buf[MAXGETHOSTSTRUCT];
	HANDLE	hResolve;
	LPCTSTR lpHost = (LPCTSTR)szHost;
	int		nResult;

	//名称无效
	if( lpHost == NULL )  return FALSE; 

	//首先假设输入地址为IP地址

	//计算长度
	iLen = strlen(lpHost);
	if(  iLen == 0 )  return FALSE; 
	//判断是否为点分的IP
	bIP = TRUE;
	nNumber = 0;   //计算输入的地址中点的个数
	for(i=0;i<iLen;i++)
	{
			if(   (lpHost[i]<'0')||(lpHost[i]>'9')    ) 
			{
				/* 判断是否为0-9字符和.符号 */
				/* lpHost是域名 */
				if( lpHost[i] == '.' ) nNumber++;
				else		 
				{
					bIP = FALSE;
					break;
				}
			}
	}
	// 输入是IP地址,不是域名
	if( bIP == TRUE )
	{
		//如果'.'符号不是3个,肯定有问题,这是针对IPv4
		if( nNumber != 3 )  return FALSE;
		else
		{
			dwIP = inet_addr( lpHost );
			// IP地址有误
			if( dwIP == INADDR_NONE ) return FALSE;
			ipServer = *((LPIN_ADDR)&dwIP);
			return TRUE;
		}
	}

	////////////////////////////////////////////
	// 解析
	/////////////////////

	//异步操作
	hResolve = WSAAsyncGetHostByName( 
					m_hMainWnd,			    //handle
					SOCKET_THREAD_RESOLVE,  //message
				    lpHost,					//source
					buf,					//result
					MAXGETHOSTSTRUCT );
	if( hResolve == 0 ) return FALSE;


	//开始等待窗口处理消息
	// 注意:
	// 如果用户选择取消,则m_bCancelJob = TRUE
	m_bCancelJob = FALSE;
	ResetEvent( m_hWaitEvent );		
    nResult = WaitForSingleObject( m_hWaitEvent, confChat.nWaitTime*2000);
	ASSERT( nResult != WAIT_TIMEOUT );
	
	if( nResult == WAIT_TIMEOUT )
	{
			m_bState = SOCKET_ERROR_TIMEOUT;
			return FALSE;
	}

	// 如果是取消解析
	if( m_bCancelJob == TRUE ) 
	{
			WSACancelAsyncRequest( hResolve );
			return FALSE;
	}

	// 解析成功
	ip = (struct hostent *)buf;
	// 如果解析的地址不是IP地址
	if( ip->h_length != sizeof(IN_ADDR) ) 
	{
		return FALSE;
	}
	memcpy( (void *)&ipServer, (void *)(ip->h_addr_list[0]) , ip->h_length );
	return TRUE;
}

void CTCPSocket::Stop()
{

	SetEvent( m_hWaitEvent );
	m_bCancelJob = TRUE;
}

void CTCPSocket::StopWait()
{

	SetEvent( m_hWaitEvent );
	m_bCancelJob = FALSE;
}

SOCKET CTCPSocket::GetSocket()
{
	return m_TCP_s;
}

BOOL CTCPSocket::CreateTransfer(CTCPSocket *pSocket, HWND hWnd, BOOL bAsync)
{

	//pSocket是SERVER的socket类,hWnd是主窗口句柄
	int		nLength = sizeof(SOCKADDR_IN);
	SOCKADDR_IN	sockClient;
	int		nResult;

	if( pSocket == NULL ) return FALSE;

	m_lpReceiveBuffer = (LPBYTE)GlobalAlloc( GPTR, MAX_PACKET_SIZE*4 );
	if( !m_lpReceiveBuffer )
	{
		m_nErrorCode = SOCKET_ERROR_CREATE;
		return FALSE;
	}
	m_lpSendBuffer = (LPBYTE)GlobalAlloc( GPTR, MAX_PACKET_SIZE+1 );
	if( !m_lpSendBuffer )
	{
		m_nErrorCode = SOCKET_ERROR_CREATE;
		return FALSE;
	}

	m_TCP_s = accept( pSocket->GetSocket(), (LPSOCKADDR)&sockClient, &nLength);
	if( m_TCP_s == INVALID_SOCKET )
	{
		//套接字无效
		m_nErrorCode = SOCKET_ERROR_ACCEPT;
		return FALSE;
	}

	///获得对方的IP地址,保存到m_szHost
	ipClient = sockClient.sin_addr;
	m_szHost.Format( "%d.%d.%d.%d",
					ipClient.S_un.S_un_b.s_b1,
					ipClient.S_un.S_un_b.s_b2,
					ipClient.S_un.S_un_b.s_b3,
					ipClient.S_un.S_un_b.s_b4 );

	if( bAsync == FALSE ) 
	{
		//不采用异步方式
		//到这里就已经结束了
		m_bSocketType = SOCKET_SERVER_TRANSFER;
		m_bState = SOCKET_CONNECTED;
		m_bCanWrite = TRUE;
		return TRUE;
	}

	////////////异步接受
	/////
	////////////////////////////////////
	m_hMainWnd = hWnd;


	nResult = WSAAsyncSelect( m_TCP_s, hWnd, SOCKET_THREAD_TRANSFER, FD_READ|FD_WRITE|FD_CLOSE );
	if( nResult == SOCKET_ERROR )
	{
		m_nErrorCode = SOCKET_ERROR_ACCEPT;
		Close();
		return FALSE;
	}

	////////成功了
	/////////可以开始收发数据
	///////////////////////////
	m_bSocketType = SOCKET_SERVER_TRANSFER;
	m_bState = SOCKET_CONNECTED;
	m_bCanWrite = TRUE;

	return TRUE;
}

CString CTCPSocket::GetHost()
{
	return m_szHost;
}



BOOL CTCPSocket::Receive()
{
	int nResult;

	//把数据从网络中读到m_lpReceiveBuffer中

	if( !m_lpReceiveBuffer ) return FALSE;

	nResult = recv( m_TCP_s, 
					(char *)(m_lpReceiveBuffer+m_nEnd), 
					MAX_PACKET_SIZE, 
					0 
				);

	ASSERT( nResult != 0 );

	m_nEnd+=nResult;

	//如何把内容传到对话框是关键问题

	return (nResult!=0);

}

int CTCPSocket::Send(LPBYTE lpBuf, int nLen)
{
	//把lpBuf中长度为nLen字节的数据发出
	int nResult;
	LPBYTE lpTemp;
	int nSendLen;

	if( m_bCanWrite == FALSE ) return SOCKET_ERROR_SEND;
	if( nLen == 0 ) return SOCKET_ERROR_SEND;
	if( nLen > MAX_PACKET_SIZE ) return SOCKET_ERROR_SEND;
	if( lpBuf == NULL ) return SOCKET_ERROR_SEND;
	

	memcpy( m_lpSendBuffer, lpBuf, nLen );
	lpTemp = m_lpSendBuffer;
	nSendLen = nLen;
	//等待FD_WRITE
	

	while( 1 )
	{
		nResult = send( m_TCP_s, (char *)lpTemp, nSendLen, 0 );
		//可能网络发生错误
		if( nResult == 0 ) return SOCKET_ERROR_CLOSE;
		if( nResult == SOCKET_ERROR )
		{
			nResult = WSAGetLastError();
			switch( nResult )
			{
			case WSAEWOULDBLOCK:
				m_bCanWrite = FALSE;
				return SOCKET_ERROR_BLOCK;
			case WSAENETRESET:
				return SOCKET_ERROR_RESET;
			default:
				return SOCKET_ERROR_SEND;
			}
		}
		if( nResult < nSendLen )
		{
			lpTemp+=nResult;
			nSendLen-=nResult;
		}
		else 
		{
			return SOCKET_ERROR_NOERROR;	
		}
	}
}

void CTCPSocket::EnableWrite()
{
	m_bCanWrite = TRUE;
}

LPBYTE CTCPSocket::GetData(int *nLen)
{
	LPBYTE lpTemp = NULL;


	if( m_lpReceiveBuffer == NULL ) return NULL;
	if( m_nBegin == m_nEnd ) return NULL;

	if( m_nEnd-m_nBegin > MAX_PACKET_SIZE )
	{
		*nLen = MAX_PACKET_SIZE;
	}
	else  *nLen = m_nEnd-m_nBegin;
	lpTemp = m_lpReceiveBuffer+m_nBegin;
	m_nBegin = 0;
	m_nEnd = 0;
	return lpTemp;
}

int CTCPSocket::SendFirstPacket()
{
	//发送连接请求
	char buf[300];
	int  nBytes;

	if(  
	  		(confChat.bProxyUsable == PROXY_AUTH_UNSET)
		   ||(confChat.bProxyUsable == PROXY_AUTH_NOPASS)
	  )
	{
			memset( buf, 0, 300 );
			wsprintf( buf, "%s%s:%d%s",
						"CONNECT ",
						m_szHost,
						m_nPort,
						" HTTP/1.1\r\nUser-Agent: NetChat/0.1\r\n\r\n");
			nBytes = strlen( buf );
			return Send((LPBYTE)buf, nBytes );
	}
	else
	{
			memset( buf, 0, 300 );
			wsprintf( buf, "%s%s:%d%s%s\r\n\r\n",
						"CONNECT ",
						m_szHost,
						m_nPort,
						" HTTP/1.1\r\nUser-Agent: PCTel/0.3\r\n",
						(LPSTR)(LPCTSTR)confChat.szProxyPass
						);
			nBytes = strlen( buf );
			return Send((LPBYTE)buf, nBytes);
		}
}

BOOL CTCPSocket::ChangeHandle()
{
	int nResult;

	if( m_TCP_s == INVALID_SOCKET) return FALSE;
	if( m_bSocketType != SOCKET_CLIENT ) return FALSE;
	if( m_bState != SOCKET_CONNECTED ) return FALSE;
	if( m_bUseProxy == FALSE ) return FALSE;

	WSAAsyncSelect( m_TCP_s , m_hMainWnd, 0, 0 );

	m_hMainWnd = m_hFinalWnd;
	nResult = WSAAsyncSelect( 
					m_TCP_s, 
					m_hMainWnd, 
					SOCKET_THREAD_TRANSFER, 
					FD_READ|FD_WRITE|FD_CLOSE
				);
	if( nResult == SOCKET_ERROR )
	{
		m_nErrorCode = SOCKET_ERROR_CONNECT;
		return FALSE;
	}
	return TRUE;
}

⌨️ 快捷键说明

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