📄 netclient.cpp
字号:
// NetClient.cpp: implementation of the CNetClient class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "NetClient.h"
//#include <fstream.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CNetClient::CNetClient()
{
IsStart=false;
bOprUnInit=false;
m_pProcessRecvData=NULL;
hSendEvent=CreateEvent(NULL,false,false,NULL);
hWorkEvent=CreateEvent(NULL,false,false,NULL);
hExitEvent=CreateEvent(NULL,false,false,NULL);
}
CNetClient::~CNetClient()
{
CloseHandle(hSendEvent);
CloseHandle(hWorkEvent);
CloseHandle(hExitEvent);
}
DWORD _stdcall SendProc(LPVOID pParam)
{
CNetClient * pNetClient=(CNetClient*) pParam;
HANDLE event[2];
event[0]=pNetClient->hSendEvent;
event[1]=pNetClient->hExitEvent;
while(true)
{
Sleep(1);
::EnterCriticalSection(&pNetClient->SendMsgQueSection);
//队列为空,等待发送事件触发
if(pNetClient->SendMsgQueue.IsEmpty())
{
::LeaveCriticalSection(&pNetClient->SendMsgQueSection);
//为空,或者发送完毕
ResetEvent(pNetClient->hSendEvent);
TRACE(L"\nTheSendProc Is Waiting....");
DWORD Index=::WaitForMultipleObjects(2,event,false,INFINITE);
if((Index-WAIT_OBJECT_0)==1)return 0L;
}
else
{
//取下一个结点,并发送
MSG_NODE p=pNetClient->SendMsgQueue.DeQueue();
//释放队列
::LeaveCriticalSection(&pNetClient->SendMsgQueSection);
DWORD retlen;
bool bRet=pNetClient->m_sClient.SendMsg(p.pData,p.DataLength,&retlen,WSA_INFINITE);
if(bRet==false || retlen!=p.DataLength)
{
if(GetLastError()!=CLIENT_FUNERROR)
pNetClient->m_pProcessRecvData(NULL,0,0);
pNetClient->UnInit();
}
}
}
return 0L;
}
DWORD _stdcall WorkProc(LPVOID pParam)
{
CNetClient* pNetClient=(CNetClient*)pParam;
HANDLE event[2];
event[0]=pNetClient->hWorkEvent;
event[1]=pNetClient->hExitEvent;
while(true)
{
Sleep(1);
::EnterCriticalSection(&pNetClient->RecvMsgQueSection);
//队列为空,等待发送事件触发
if(pNetClient->RecvMsgQueue.IsEmpty())
{
::LeaveCriticalSection(&pNetClient->RecvMsgQueSection);
//为空,或者发送完毕
ResetEvent(pNetClient->hWorkEvent);
TRACE(L"\nTheWorkProc Is Waiting....");
DWORD Index=::WaitForMultipleObjects(2,event,false,INFINITE);
if((Index-WAIT_OBJECT_0)==1)return 0L;
}
else
{
//取下一个结点,并发送
MSG_NODE p=pNetClient->RecvMsgQueue.DeQueue();
//释放队列
::LeaveCriticalSection(&pNetClient->RecvMsgQueSection);
//调用回调函数,处理数据
pNetClient->m_pProcessRecvData(p.pData,p.DataLength,pNetClient->m_dwUserData);
}
}
return 0L;
}
DWORD _stdcall RecvProc(LPVOID pParam)
{
CNetClient * pNetClient=(CNetClient*)pParam;
char RecvBuf[BUFFER_SIZE];
DWORD retlen;
while (true)
{
Sleep(1);
TRACE(L"\nTheRecvThread Is Waiting...");
if(!pNetClient->m_sClient.RecvMsg(RecvBuf,BUFFER_SIZE,&retlen,WSA_INFINITE) && GetLastError()!=CLIENT_FUNERROR)
{
if(pNetClient->bOprUnInit)return 0L;//应用程序请求退出
//连接已经被断开,通知上层(通过调用回调函数)
pNetClient->m_pProcessRecvData(NULL,0,0);
pNetClient->UnInit();
return 0L;
}
else
{
//没收到字节?还是出错
if(retlen==0)
{
pNetClient->m_pProcessRecvData(NULL,0,0);
pNetClient->UnInit();
return 0L;
}
//将接收到的数据放到接收队列里
MSG_NODE Msg;
Msg.DataLength=retlen;
memcpy(Msg.pData,RecvBuf,retlen);
//插入消息队列
::EnterCriticalSection(&pNetClient->RecvMsgQueSection);
if(pNetClient->SendMsgQueue.IsEmpty())
{
pNetClient->RecvMsgQueue.EnQueue(Msg);
::LeaveCriticalSection(&pNetClient->RecvMsgQueSection);
//如果消息队列为空,告诉工作线程可以进行工作了
SetEvent(pNetClient->hWorkEvent);
}
else
{
pNetClient->RecvMsgQueue.EnQueue(Msg);
::LeaveCriticalSection(&pNetClient->RecvMsgQueSection);
}
}
}
return 0L;
}
bool CNetClient::Init(ProcessRecvData* pProcessRecvData,LPCSTR szSvrAddr, unsigned long iSvrPort,DWORD userdata)
{
if(pProcessRecvData==NULL //回调函数空
|| szSvrAddr==NULL //地址空
|| IsStart)//已经启动过了
return false;
::InitializeCriticalSection(&SendMsgQueSection);
::InitializeCriticalSection(&RecvMsgQueSection);
IsStart=false;
bOprUnInit=false;
m_pProcessRecvData=pProcessRecvData;
m_dwUserData=userdata;
int bRet=InitNetWork(szSvrAddr,iSvrPort,HostIpAddr);
if(0==bRet)
{
IsStart=true;
return true;
}
else
return false;
}
void CNetClient::UnInit()
{
if(!IsStart)return;
bOprUnInit=true;
SetEvent(hExitEvent);
SetEvent(hExitEvent);
m_sClient.UnInit();
::DeleteCriticalSection(&SendMsgQueSection);
::DeleteCriticalSection(&RecvMsgQueSection);
SendMsgQueue.MakeEmpty();
RecvMsgQueue.MakeEmpty();
m_pProcessRecvData=NULL;
IsStart=false;
}
int CNetClient::InitNetWork(LPCSTR szSvrAddr,unsigned int SvrPort,LPCSTR pHostIpAddress)
{
CString LogStr;
int Error=0;
WSADATA wsaData;
char Name[100];
hostent *pHostEntry;
in_addr rAddr;
memset((void *)pHostIpAddress,0,sizeof(pHostIpAddress));
//Net Start Up
Error=WSAStartup(MAKEWORD(0x02,0x02),&wsaData);
if(Error!=0)
{
Error = WSAGetLastError();
LogStr.Format(L"WSAStartUp Faild With Error: %d",Error);
WriteLogString(LogStr);
return Error;
}
//Make Version
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 )
{
WSACleanup( );
//WriteLogString("The Local Net Version Is not 2");
return -1;
}
//Get Host Ip
Error = gethostname ( Name, sizeof(Name) );
if( 0 == Error )
{
pHostEntry = gethostbyname( Name );
if( pHostEntry != NULL )
{
memcpy( &rAddr, pHostEntry->h_addr_list[0], sizeof(struct in_addr) );
sprintf((char * )pHostIpAddress,"%s",inet_ntoa( rAddr ));
}
else
{
Error = WSAGetLastError();
LogStr.Format(L"GetHostIp faild with Error: %d",Error);
//WriteLogString(LogStr);
}
}
else
{
Error = WSAGetLastError();
LogStr.Format(L"gethostname faild with Error: %d",Error);
//WriteLogString(LogStr);
}
//Socket Create
if(0==Error)
{
if(!m_sClient.CreateSocket(SOCK_STREAM))
{
Error=WSAGetLastError();
LogStr.Format(L"Create Client Socket Faild :%d",Error);
//WriteLogString(LogStr);
return Error;
}
}
if(0==Error)
{
if(!m_sClient.ConnectSocket((char *)szSvrAddr,SvrPort))
{
Error=WSAGetLastError();
LogStr.Format(L"Create Client Socket Faild :%d",Error);
WriteLogString(LogStr);
return Error;
}
}
//启动工作线程,并升高工作线程的等级至最高
if(0==Error)
{
HANDLE WorkHan=0;
unsigned long WorkID;
if((WorkHan=CreateThread(NULL,0,WorkProc,this,0,&WorkID))==NULL)
{
Error=GetLastError();
LogStr.Format(L"Create WorkThread Faild With Error %d",Error);
WriteLogString(LogStr);
return Error;
}
SetThreadPriority(WorkHan,THREAD_PRIORITY_HIGHEST);
CloseHandle(WorkHan);
}
//启动接收线程
if(0==Error)
{
HANDLE RecvHan=0;
unsigned long RecvID;
if((RecvHan=CreateThread(NULL,0,RecvProc,this,0,&RecvID))==NULL)
{
Error=GetLastError();
LogStr.Format(L"Create RecvThread Faild With Error %d",Error);
WriteLogString(LogStr);
SetEvent(hExitEvent);//退出先前创建的线程
return Error;
}
CloseHandle(RecvHan);
}
//启动发送线程
if(0==Error)
{
HANDLE ThreHan;
unsigned long ThrID;
if((ThreHan=CreateThread(NULL,0,SendProc,this,0,&ThrID))==NULL)
{
Error=GetLastError();
LogStr.Format(L"Create SEND Thred Faild With Error %d",Error);
WriteLogString(LogStr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -