📄 clientsocket.cpp
字号:
bool __cdecl CClientSocket::SendData(WORD wMainCmdID, WORD wSubCmdID, void * pData, WORD wDataSize)
{
//效验状态
if (m_hSocket==INVALID_SOCKET) return false;
if (m_SocketState!=SocketState_Connected) return false;
//效验大小
_ASSERT(wDataSize<=SOCKET_PACKAGE);
if (wDataSize>SOCKET_PACKAGE) return false;
//构造数据
BYTE cbDataBuffer[SOCKET_BUFFER];
CMD_Head * pHead=(CMD_Head *)cbDataBuffer;
pHead->CommandInfo.wMainCmdID=wMainCmdID;
pHead->CommandInfo.wSubCmdID=wSubCmdID;
if (wDataSize>0)
{
_ASSERT(pData!=NULL);
CopyMemory(pHead+1,pData,wDataSize);
}
WORD wSendSize = sizeof(CMD_Head)+wDataSize;
pHead->CmdInfo.wDataSize=wSendSize;
pHead->CmdInfo.cbMessageVer=SOCKET_VER;
if(m_bEncrypted){
//加密数据
wSendSize=EncryptBuffer(cbDataBuffer,sizeof(CMD_Head)+wDataSize,sizeof(cbDataBuffer));
}
m_dwSendPacketCount++;
//发送数据
return SendBuffer(cbDataBuffer,wSendSize);
}
//关闭连接
bool __cdecl CClientSocket::CloseSocket(bool bNotify)
{
//关闭连接
bool bClose=(m_hSocket!=INVALID_SOCKET);
m_SocketState=SocketState_NoConnect;
if (m_hSocket!=INVALID_SOCKET)
{
WSAAsyncSelect(m_hSocket,m_hWnd,WM_SOCKET_NOTIFY,0);
closesocket(m_hSocket);
m_hSocket=INVALID_SOCKET;
m_SocketState=SocketState_NoConnect;
}
if ((bNotify==true)&&(bClose==true))
{
try { m_AttemperEvent.PostSocketCloseEvent(); }
catch (...) {}
}
//恢复数据
m_wRecvSize=0;
m_cbSendRound=0;
m_cbRecvRound=0;
m_dwSendXorKey=0;
m_dwRecvXorKey=0;
m_dwSendTickCount=0;
m_dwRecvTickCount=0;
m_dwSendPacketCount=0;
m_dwRecvPacketCount=0;
m_bCloseByServer=false;
return true;
}
//发送数据
bool CClientSocket::SendBuffer(void * pBuffer, WORD wSendSize)
{
//效验参数
_ASSERT(wSendSize!=0);
_ASSERT(pBuffer!=NULL);
//发送数据
WORD wSended=0;
while (wSended<wSendSize)
{
int iErrorCode=send(m_hSocket,(char *)pBuffer+wSended,wSendSize-wSended,0);
if (iErrorCode==SOCKET_ERROR)
{
if (WSAGetLastError()==WSAEWOULDBLOCK)
{
m_dwSendTickCount=GetTickCount()/1000L;
return true;
}
return false;
}
wSended+=iErrorCode;
}
m_dwSendTickCount=GetTickCount()/1000L;
return true;
}
//随机映射
WORD CClientSocket::SeedRandMap(WORD wSeed)
{
DWORD dwHold=wSeed;
return (WORD)((dwHold=dwHold*241103L+2533101L)>>16);
}
//映射发送数据
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)
{
//效验参数
_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=rand();
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_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_AttemperEvent.PostSocketConnectEvent(iErrorCode,szErrorDesc);
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 = wPacketSize;
if(m_bEncrypted){
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_AttemperEvent.PostSocketReadEvent(Command,pDataBuffer,wDataSize);
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;
}
//创建工作窗口
HWND CClientSocket::MakeWorkerWindow(){
WNDCLASS wndclass;
CHAR *ProviderClass = "OGFSocket";
HWND hWindow;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = (WNDPROC)WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = NULL;
wndclass.hIcon = NULL;
wndclass.hCursor = NULL;
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = ProviderClass;
if(RegisterClass(&wndclass) == 0)
return NULL;
if((hWindow = CreateWindow(
ProviderClass,
"",
WS_OVERLAPPEDWINDOW,
0,
0,
0,
0,
NULL,
NULL,
NULL,
NULL)) == NULL)
{
return NULL;
}
SetWindowLongPtr(hWindow, GWLP_USERDATA, (LONG_PTR)(this));
DWORD dwError = GetLastError();
//
return hWindow;
}
LRESULT CALLBACK CClientSocket::WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if(uMsg==WM_SOCKET_NOTIFY){
LONG_PTR lPtr = GetWindowLongPtr(hWnd, GWLP_USERDATA);
CClientSocket* pClientSocket = reinterpret_cast<CClientSocket*>(lPtr);
pClientSocket->OnSocketNotify(wParam, lParam);
}
return DefWindowProc(hWnd, uMsg, wParam,lParam);
}
//////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -