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

📄 netengineclient.cpp

📁 采用完成端口的client/server DLL源码
💻 CPP
字号:
#include "netengineclient.h"

NetEngineClient* NetEngineClient::m_pMe = NULL;

NetEngineClient::NetEngineClient( MsgFun a_pFun )
{
	m_pMsgProcessFun			= a_pFun;
	NetEngineClient::m_pMe		= this;
	m_NetSocket					= NULL;
	m_hEvent					= CreateEvent( NULL,0,0,0 );
}

NetEngineClient::~NetEngineClient( void )
{
	//断开连接
	this->Disconnect();
}

NetEngineClient* NetEngineClient::Instance( void )
{
	if( m_pMe ){
		return m_pMe;
	}
	return NULL;
}

bool NetEngineClient::SendBuf( void* a_pBuf,DWORD a_dwLen )
{
	if( m_NetSocket == NULL ){
		return false;
	}

	send( m_NetSocket,(char*)a_pBuf,a_dwLen,0 );
	Sleep(0);
	return true;
}

bool NetEngineClient::Connect( char* a_pIP,DWORD a_dwPort )
{
	if( m_NetSocket == NULL )
	{
		//初始化WS2.0网络
		WSADATA		t_wsaData;
		WSAStartup(MAKEWORD(2,2),&t_wsaData);
	}
	//初始化地址
	sockaddr_in  t_sServAddr;
	memset(&t_sServAddr, 0, sizeof(sockaddr_in));
	t_sServAddr.sin_family			= AF_INET;
	t_sServAddr.sin_addr.s_addr		= inet_addr( a_pIP );
    t_sServAddr.sin_port			= htons( a_dwPort );

	m_NetSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

	//设置缓冲区为0
	int t_iZero = 1024*18;
	if(setsockopt(m_NetSocket, SOL_SOCKET,SO_SNDBUF,(char*)&t_iZero,sizeof(t_iZero))==SOCKET_ERROR)
	{
		MessageBox(NULL,"setsockopt","setsockopt",NULL);
	}
	//连接
	int err = connect( m_NetSocket, (struct sockaddr *)&t_sServAddr,sizeof(t_sServAddr) );
	
	if( err == SOCKET_ERROR ){
		return false;
	}
	
	// 设置异步通讯
	if( WSAEventSelect( m_NetSocket, m_hEvent, FD_READ|FD_CLOSE ) == SOCKET_ERROR )
	{
		return false;
	}
	//创建线程
	if( !this->CreateWorkThread() )
	{
		return false;
	}
	return true;
}

bool NetEngineClient::Disconnect( void )
{
	NetEngineClient::Instance()->MsgProcess( NULL,NET_MSG_CLOSE );
	WSACleanup();
	closesocket( m_NetSocket );
	CloseHandle( m_hEvent );
	m_NetSocket = NULL;
	Sleep(50);
	return true;
}

const SOCKET NetEngineClient::GetNetSocket( void )
{
	return m_NetSocket;
}

bool NetEngineClient::CreateWorkThread( void )
{
	DWORD        t_dwThreadId;

	//创建线程
	HANDLE t_hThread;
	t_hThread = CreateThread(
		NULL, 0, NetEngineClient::ThreadFunc, NULL, 0, &t_dwThreadId
		);
	if( t_hThread )
	{
		CloseHandle(t_hThread);
		return true;
	}
	return false;
}

DWORD WINAPI NetEngineClient::ThreadFunc( LPVOID a_pVoid )
{
	bool     t_bIsRun = true;
	HANDLE   t_hTemp  = NetEngineClient::Instance()->GetHandle();

	while( t_bIsRun )		// 网络消息循环
	{
		DWORD err = WaitForMultipleObjects(1, &t_hTemp, false, INFINITE);
		if( err-WAIT_OBJECT_0 == 1 )
		{
			MessageBox(NULL,"ThreadFunc","err-WAIT_OBJECT_0 == 1",NULL);
			break;	// 结束线程
		}
		
		WSANETWORKEVENTS SocketEvents;
		try
		{
			// 枚举网络事件
			DWORD ret = WSAEnumNetworkEvents(NetEngineClient::Instance()->GetNetSocket(), NetEngineClient::Instance()->GetHandle(), &SocketEvents);
			
			if( SocketEvents.lNetworkEvents != 0 )
			{
				// 接受网络连接请求(Server)
				switch( SocketEvents.lNetworkEvents )
				{
				case FD_READ:
					{
						NetEngineClient::Instance()->RecvBuf();
					}
					break;
				case FD_CLOSE:
					{
						t_bIsRun = false;
						NetEngineClient::Instance()->Disconnect();
					}
					break;
				default:
					break;
				}
			}
		}
		catch(...)
		{
			static DWORD oldtime = 0;
			DWORD newtime = timeGetTime();
			if( newtime - oldtime >= 60000 )
			{
				oldtime = newtime;
				MessageBox(NULL,"ThreadFunc","网络连接超时",NULL);
			}
		}
		Sleep(0);		// 释放线程控制权
	}
	return 0;
}

bool NetEngineClient::MsgProcess( void* a_pBuf,NET_MSG a_eMsg )
{
	return m_pMsgProcessFun( a_pBuf,a_eMsg );
}

HANDLE NetEngineClient::GetHandle( void )
{
	return m_hEvent;
}

bool NetEngineClient::RecvBuf( void )
{
	int err,t_iSize;

	t_iSize = 0;
	//清空缓冲区
	memset( m_cBuffer, 0, DATA_BUFSIZE );
	//接收包SIZE
	err = recv( m_NetSocket,(char*)&t_iSize,sizeof(int),0 );
	if( err == SOCKET_ERROR )
	{
		this->Disconnect();
		return 0;
	}
	int t_iLeft		= t_iSize;
	int t_iIDX		= 0;
	while ( t_iLeft > 0 ) 
	{
		err = recv( m_NetSocket,&m_cBuffer[t_iIDX],t_iLeft,0 );
		if( err == SOCKET_ERROR )
		{
			if( WSAEWOULDBLOCK == WSAGetLastError() )
			{
				Sleep(5);
			}
			else
			{
				NetEngineClient::Instance()->Disconnect();
				return 0;
			}
		}
		else
		{
			t_iLeft -= err;
			t_iIDX  += err;
		}
	}
	//激活接受消息事件
	this->MsgProcess( m_cBuffer,NET_MSG_RECV );
	return true;
}

⌨️ 快捷键说明

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