📄 clientsocket.cpp
字号:
//映射发送数据
BYTE CClientSocket::MapSendByte(BYTE const cbData)
{
BYTE cbMap=m_SendByteMap[(BYTE)(cbData+m_cbSendRound)];
m_cbSendRound+=3;
return cbMap;
}
//映射接收数据
BYTE CClientSocket::MapRecvByte(BYTE const cbData)
{
BYTE cbMap=m_RecvByteMap[cbData]-m_cbRecvRound;
m_cbRecvRound+=3;
return cbMap;
}
//解释服务器地址
DWORD CClientSocket::TranslateAddr(LPCTSTR pszServerAddr)
{
//转化地址
DWORD dwServerIP=inet_addr(pszServerAddr);
if (dwServerIP==INADDR_NONE)
{
LPHOSTENT lpHost=gethostbyname(pszServerAddr);
if (lpHost==NULL) return INADDR_NONE;
dwServerIP=((LPIN_ADDR)lpHost->h_addr)->s_addr;
}
return dwServerIP;
}
//解释错误
LPCTSTR CClientSocket::GetConnectError(int iErrorCode, LPTSTR pszBuffer, WORD wBufferSize)
{
//效验参数
ASSERT(pszBuffer!=NULL);
if (pszBuffer==NULL) return NULL;
//解释错误
switch (iErrorCode)
{
case 0: //没有错误
{
lstrcpyn(pszBuffer,TEXT("操作执行成功"),wBufferSize);
break;
}
case WSAEADDRNOTAVAIL: //地址格式错误
{
lstrcpyn(pszBuffer,TEXT("目标服务器地址格式不正确,请检查后再次尝试!"),wBufferSize);
break;
}
case WSAECONNREFUSED: //服务器没有启动
{
lstrcpyn(pszBuffer,TEXT("目标服务器繁忙或者没有启动!"),wBufferSize);
break;
}
case WSAETIMEDOUT: //连接超时
{
lstrcpyn(pszBuffer,TEXT("连接超时,可能是目标服务器不存在或者服务器地址格式不正确!"),wBufferSize);
break;
}
case WSAEHOSTUNREACH:
{
lstrcpyn(pszBuffer,TEXT("网络连接失败,请检查是否已经成功拨号和连接 Internet !"),wBufferSize);
break;
}
default: //默认错误
{
_snprintf(pszBuffer,wBufferSize,TEXT("连接错误号:%ld,详细错误信息请参考操作帮助手册!"),iErrorCode);
break;
}
}
return pszBuffer;
}
//加密数据
WORD CClientSocket::EncryptBuffer(BYTE pcbDataBuffer[], WORD wDataSize, WORD wBufferSize)
{
int i = 0;
//效验参数
ASSERT(wDataSize>=sizeof(CMD_Head));
ASSERT(wBufferSize>=(wDataSize+2*sizeof(DWORD)));
ASSERT(wDataSize<=(sizeof(CMD_Head)+SOCKET_PACKAGE));
//调整长度
WORD wEncryptSize=wDataSize-sizeof(CMD_Command),wSnapCount=0;
if ((wEncryptSize%sizeof(DWORD))!=0)
{
wSnapCount=sizeof(DWORD)-wEncryptSize%sizeof(DWORD);
memset(pcbDataBuffer+sizeof(CMD_Info)+wEncryptSize,0,wSnapCount);
}
//效验码与字节映射
BYTE cbCheckCode=0;
for (WORD i=sizeof(CMD_Info);i<wDataSize;i++)
{
cbCheckCode+=pcbDataBuffer[i];
pcbDataBuffer[i]=MapSendByte(pcbDataBuffer[i]);
}
//填写信息头
CMD_Head * pHead=(CMD_Head *)pcbDataBuffer;
pHead->CmdInfo.cbCheckCode=~cbCheckCode+1;
pHead->CmdInfo.wDataSize=wDataSize;
pHead->CmdInfo.cbMessageVer=SOCKET_VER;
//创建密钥
DWORD dwXorKey=m_dwSendXorKey;
if (m_dwSendPacketCount==0)
{
//生成第一次随机种子
GUID Guid;
CoCreateGuid(&Guid);
dwXorKey=GetTickCount()*GetTickCount();
dwXorKey^=Guid.Data1;
dwXorKey^=Guid.Data2;
dwXorKey^=Guid.Data3;
dwXorKey^=*((DWORD *)Guid.Data4);
//随机映射种子
dwXorKey=SeedRandMap((WORD)dwXorKey);
dwXorKey|=((DWORD)SeedRandMap((WORD)(dwXorKey>>16)))<<16;
dwXorKey^=g_dwPacketKey;
m_dwSendXorKey=dwXorKey;
m_dwRecvXorKey=dwXorKey;
}
//加密数据
WORD * pwSeed=(WORD *)(pcbDataBuffer+sizeof(CMD_Info));
DWORD * pdwXor=(DWORD *)(pcbDataBuffer+sizeof(CMD_Info));
WORD wEncrypCount=(wEncryptSize+wSnapCount)/sizeof(DWORD);
for (i=0;i<wEncrypCount;i++)
{
*pdwXor++^=dwXorKey;
dwXorKey=SeedRandMap(*pwSeed++);
dwXorKey|=((DWORD)SeedRandMap(*pwSeed++))<<16;
dwXorKey^=g_dwPacketKey;
}
//插入密钥
if (m_dwSendPacketCount==0)
{
MoveMemory(pcbDataBuffer+sizeof(CMD_Head)+sizeof(DWORD),pcbDataBuffer+sizeof(CMD_Head),wDataSize);
*((DWORD *)(pcbDataBuffer+sizeof(CMD_Head)))=m_dwSendXorKey;
pHead->CmdInfo.wDataSize+=sizeof(DWORD);
wDataSize+=sizeof(DWORD);
}
//设置变量
m_dwSendPacketCount++;
m_dwSendXorKey=dwXorKey;
return wDataSize;
}
//解密数据
WORD CClientSocket::CrevasseBuffer(BYTE pcbDataBuffer[], WORD wDataSize)
{
//效验参数
ASSERT(m_dwSendPacketCount>0);
ASSERT(wDataSize>=sizeof(CMD_Head));
ASSERT(((CMD_Head *)pcbDataBuffer)->CmdInfo.wDataSize==wDataSize);
//调整长度
WORD wSnapCount=0;
if ((wDataSize%sizeof(DWORD))!=0)
{
wSnapCount=sizeof(DWORD)-wDataSize%sizeof(DWORD);
memset(pcbDataBuffer+wDataSize,0,wSnapCount);
}
//解密数据
DWORD dwXorKey=m_dwRecvXorKey;
DWORD * pdwXor=(DWORD *)(pcbDataBuffer+sizeof(CMD_Info));
WORD * pwSeed=(WORD *)(pcbDataBuffer+sizeof(CMD_Info));
WORD wEncrypCount=(wDataSize+wSnapCount-sizeof(CMD_Info))/4;
for (WORD i=0;i<wEncrypCount;i++)
{
if ((i==(wEncrypCount-1))&&(wSnapCount>0))
{
BYTE * pcbKey=((BYTE *)&m_dwRecvXorKey)+sizeof(DWORD)-wSnapCount;
CopyMemory(pcbDataBuffer+wDataSize,pcbKey,wSnapCount);
}
dwXorKey=SeedRandMap(*pwSeed++);
dwXorKey|=((DWORD)SeedRandMap(*pwSeed++))<<16;
dwXorKey^=g_dwPacketKey;
*pdwXor++^=m_dwRecvXorKey;
m_dwRecvXorKey=dwXorKey;
}
//效验码与字节映射
CMD_Head * pHead=(CMD_Head *)pcbDataBuffer;
BYTE cbCheckCode=pHead->CmdInfo.cbCheckCode;
for (int i=sizeof(CMD_Info);i<wDataSize;i++)
{
pcbDataBuffer[i]=MapRecvByte(pcbDataBuffer[i]);
cbCheckCode+=pcbDataBuffer[i];
}
if (cbCheckCode!=0) throw TEXT("数据包效验码错误");
return wDataSize;
}
//网络连接
LRESULT CClientSocket::OnSocketNotifyConnect(WPARAM wParam, LPARAM lParam)
{
//判断状态
int iErrorCode=WSAGETSELECTERROR(lParam);
if (iErrorCode==0) m_SocketState=SocketState_Connected;
else CloseSocket(false);
//发送通知
TCHAR szErrorDesc[128]=TEXT("");
GetConnectError(iErrorCode,szErrorDesc,sizeof(szErrorDesc));
m_pIClientSocketSink->OnSocketConnect(iErrorCode,szErrorDesc,this);
return 1;
}
//网络读取
LRESULT CClientSocket::OnSocketNotifyRead(WPARAM wParam, LPARAM lParam)
{
try
{
//读取数据
int iRetCode=recv(m_hSocket,(char *)m_cbRecvBuf+m_wRecvSize,sizeof(m_cbRecvBuf)-m_wRecvSize,0);
if (iRetCode==SOCKET_ERROR) throw TEXT("网络连接关闭,读取数据失败");
ASSERT(m_dwSendPacketCount>0);
m_wRecvSize+=iRetCode;
m_dwRecvTickCount=GetTickCount()/1000L;
//变量定义
WORD wPacketSize=0;
BYTE cbDataBuffer[SOCKET_PACKAGE+sizeof(CMD_Head)];
CMD_Head * pHead=(CMD_Head *)m_cbRecvBuf;
while (m_wRecvSize>=sizeof(CMD_Head))
{
//效验参数
wPacketSize=pHead->CmdInfo.wDataSize;
ASSERT(pHead->CmdInfo.cbMessageVer==SOCKET_VER);
ASSERT(wPacketSize<=(SOCKET_PACKAGE+sizeof(CMD_Head)));
if (pHead->CmdInfo.cbMessageVer!=SOCKET_VER) throw TEXT("数据包版本错误");
if (wPacketSize>(SOCKET_PACKAGE+sizeof(CMD_Head))) throw TEXT("数据包太大");
if (m_wRecvSize<wPacketSize) return 1;
//拷贝数据
m_dwRecvPacketCount++;
CopyMemory(cbDataBuffer,m_cbRecvBuf,wPacketSize);
m_wRecvSize-=wPacketSize;
MoveMemory(m_cbRecvBuf,m_cbRecvBuf+wPacketSize,m_wRecvSize);
//解密数据
WORD wRealySize=CrevasseBuffer(cbDataBuffer,wPacketSize);
ASSERT(wRealySize>=sizeof(CMD_Head));
//解释数据
WORD wDataSize=wRealySize-sizeof(CMD_Head);
void * pDataBuffer=cbDataBuffer+sizeof(CMD_Head);
CMD_Command Command=((CMD_Head *)cbDataBuffer)->CommandInfo;
//内核命令
if (Command.wMainCmdID==MDM_KN_COMMAND)
{
switch (Command.wSubCmdID)
{
case SUB_KN_DETECT_SOCKET: //网络检测
{
//发送数据
SendData(MDM_KN_COMMAND,SUB_KN_DETECT_SOCKET,pDataBuffer,wDataSize);
break;
}
}
continue;
}
//处理数据
bool bSuccess=m_pIClientSocketSink->OnSocketRead(Command,pDataBuffer,wDataSize,this);
if (bSuccess==false) throw TEXT("网络数据包处理失败");
};
}
catch (...)
{
CloseSocket(true);
}
return 1;
}
//网络关闭
LRESULT CClientSocket::OnSocketNotifyClose(WPARAM wParam, LPARAM lParam)
{
m_bCloseByServer=true;
CloseSocket(true);
return 1;
}
//SOCKET 消息处理程序
LRESULT CClientSocket::OnSocketNotify(WPARAM wParam, LPARAM lParam)
{
switch (WSAGETSELECTEVENT(lParam))
{
case FD_CONNECT: //网络连接
{
return OnSocketNotifyConnect(wParam,lParam);
}
case FD_READ: //数据读取
{
return OnSocketNotifyRead(wParam,lParam);
}
case FD_CLOSE: //网络关闭
{
return OnSocketNotifyClose(wParam,lParam);
}
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
//建立对象函数
extern "C" __declspec(dllexport) void * __cdecl CreateClientSocket(const GUID & Guid, DWORD dwInterfaceVer)
{
//建立对象
CClientSocket * pClientSocket=NULL;
try
{
pClientSocket=new CClientSocket();
if (pClientSocket==NULL) throw TEXT("创建失败");
void * pObject=pClientSocket->QueryInterface(Guid,dwInterfaceVer);
if (pObject==NULL) throw TEXT("接口查询失败");
return pObject;
}
catch (...) {}
//清理对象
SafeDelete(pClientSocket);
return NULL;
}
//////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -