#include "StdAfx.h" #include "IClientImpl.h" #include #include #include "crc32.h" #include "ThreadPool.hpp" const int AF_IPV4 = 0; const int AF_IPV6 = 1; const int SOCK_TCP = SOCK_STREAM-1; const int SOCK_UDP = SOCK_DGRAM-1; TCHAR g_szServerIP[MAX_PATH] = _T("127.0.0.1"); TCHAR g_szCmdPort[MAX_PATH] = _T("5678"); SENDHEAD g_tSendhead = {0}; DWORD g_dwSendCode = 0; DWORD g_dwLeng = 0; BYTE *g_pData = NULL; DWORD g_dwLeng2 = 0; BYTE *g_pData2 = NULL; DWORD g_dwcount; BOOL g_bConnLYFZ = 0; int g_conntype = 0;//正常 BOOL g_bReturned = FALSE; //IClientImpl* IClientImpl::m_pTcpClient[TCPCLIENTNUM] = {NULL}; void GetFileName(IN const TCHAR *pFullName,OUT TCHAR *pFileName) { TCHAR szExt[_MAX_EXT]; _tsplitpath(pFullName, NULL, NULL, pFileName, szExt); _tcscat(pFileName, szExt); } unsigned int VerifyIntegrityPacket(IN void *pIntegrityPacket,IN unsigned int nPacketSize) { unsigned int checksum = 0; //if ( nPacketSize <= sizeof(STProtocolheader) ) //{ // return 0; //} unsigned char *pBody = &((unsigned char*)pIntegrityPacket)[sizeof(STProtocolheader)]; if( pBody ) checksum = crc32( 0, pBody, nPacketSize-sizeof(STProtocolheader) ); return checksum; } IClientImpl::IClientImpl():m_nMode(AF_IPV4),m_nSockType(SOCK_TCP) { m_bSocket = FALSE; m_bStopbeat = FALSE; m_hRunObject = NULL; m_hReConnectSrvThreadHandle = NULL; m_SocketClient.SetInterface(this); } IClientImpl::~IClientImpl() { //m_SocketClient.Terminate(); DisConnectServer(); } void IClientImpl::GetAddress(const SockAddrIn& addrIn, CString& rString) const { TCHAR szIPAddr[MAX_PATH] = { 0 }; CSocketHandle::FormatIP(szIPAddr, MAX_PATH, addrIn); rString.Format(_T("%s : %d"), szIPAddr, static_cast(static_cast(ntohs(addrIn.GetPort()))) ); } void IClientImpl::AppendText(LPCTSTR lpszFormat, ...) { // if ( !::IsWindow(m_ctlMsgList.GetSafeHwnd()) ) return; // TCHAR szBuffer[512]; // HWND hWnd = m_ctlMsgList.GetSafeHwnd(); // DWORD dwResult = 0; // if (SendMessageTimeout(hWnd, WM_GETTEXTLENGTH, 0, 0, SMTO_NORMAL, 500L, &dwResult) != 0) // { // int nLen = (int) dwResult; // if (SendMessageTimeout(hWnd, EM_SETSEL, nLen, nLen, SMTO_NORMAL, 500L, &dwResult) != 0) // { // size_t cb = 0; // va_list args; // va_start(args, lpszFormat); // ::StringCchVPrintfEx(szBuffer, 512, NULL, &cb, 0, lpszFormat, args); // va_end(args); // SendMessageTimeout(hWnd, EM_REPLACESEL, FALSE, reinterpret_cast(szBuffer), SMTO_NORMAL, 500L, &dwResult); // } // } } bool IClientImpl::GetDestination(SockAddrIn& addrIn) const { CString strPort; int nFamily = (m_nMode == AF_IPV4) ? AF_INET : AF_INET6; return addrIn.CreateFrom(NULL, strPort, nFamily); } bool IClientImpl::SetupMCAST() { const TCHAR szIPv4MCAST[] = TEXT("239.121.1.2"); const TCHAR szIPv6MCAST[] = TEXT("FF02:0:0:0:0:0:0:1"); // All Nodes local address bool result = false; if ( m_nSockType == SOCK_UDP ) { if ( m_nMode == AF_IPV4 ) { result = m_SocketClient->AddMembership(szIPv4MCAST, NULL); } else { result = m_SocketClient->AddMembership(szIPv6MCAST, NULL); HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); hr = hr; } } return result; } /////////////////////////////////////////////////////////////////////////////// void IClientImpl::OnThreadBegin(CSocketHandle* pSH) { ASSERT( pSH == m_SocketClient ); (pSH); CString strAddr; SockAddrIn sockAddr; m_SocketClient->GetSockName(sockAddr); GetAddress( sockAddr, strAddr ); InitializeCriticalSection(&pSH->m_hClient2SrvSection); } void IClientImpl::OnThreadExit(CSocketHandle* pSH) { ASSERT( pSH == m_SocketClient ); DeleteCriticalSection( &pSH->m_hClient2SrvSection ); (pSH); } void IClientImpl::OnConnectionDropped(CSocketHandle* pSH) { ASSERT( pSH == m_SocketClient ); (pSH); AppendText( _T("Connection lost with client.\r\n") ); } void IClientImpl::OnConnectionError(CSocketHandle* pSH, DWORD dwError) { ASSERT( pSH == m_SocketClient ); (pSH); _com_error err(dwError); AppendText( _T("Communication Error:\r\n%s\r\n"), err.ErrorMessage() ); } void IClientImpl::OnDataReceived(CSocketHandle* pSH, const BYTE* pbData, DWORD dwCount, const SockAddrIn& addr) { ASSERT( pSH == m_SocketClient ); (pSH); if( !m_SocketClient->IsOpen() ) return; // 处理接收回来的数据; ToprocessRecivebuf(pSH,pbData,dwCount); } void IClientImpl::ToprocessRecivebuf(IN CSocketHandle *pSockHandle, IN const BYTE* pReceivebuf, IN DWORD dwReceiveSize) { if (NULL == pReceivebuf) return; TMessageHeader* pHeader = (TMessageHeader *)pReceivebuf; char *pDataBuf = (char *)pReceivebuf + MESSAGE_HEADER_LEN; WORD dwMessageID = pHeader->wMessageId; switch (dwMessageID) { case MSG_LOGIN_RESP: case (MSG_LOGIN_RESP + 0X2FFF) : { LOGIN_RESULT_STRU tLoginResult = { 0 }; memcpy(&tLoginResult, pDataBuf, sizeof(LOGIN_RESULT_STRU)); ProcessLoginResponse(&tLoginResult); break; } case MSG_USERINFO_RESP: { TUSERLIST_INFO_STRU tUserListInfo = { 0 }; memcpy(&tUserListInfo, pDataBuf, sizeof(TUSERLIST_INFO_STRU)); // ProcessUserListInfoResponse(&tUserListInfo); break; } case MSG_LOGOUT_RESP: { TUSERLIST_INFO_STRU tUserListInfo = { 0 }; memcpy(&tUserListInfo, pDataBuf, sizeof(TUSERLIST_INFO_STRU)); // ProcessLogoutResponse(&tUserListInfo); break; } case MSG_CHATMESSAGE_RESP: case (MSG_CHATMESSAGE_RESP + 0X4FFF) : { TCHAT_MESSAGE_STRU *pChatMessage = (TCHAT_MESSAGE_STRU *)pDataBuf; ProcessChatMessageResponse_g((void *)pChatMessage); break; } default: break; } } BOOL IClientImpl::ProcessLoginRequest() { // 1.设置通信类型MSG_LOGIN_REQ,为登陆请求; WORD wMessageId = 0; wMessageId = MSG_LOGIN_REQ; BYTE *bySend = NULL; INT nDataLen = sizeof(TMessageHeader) + sizeof(TLOGIN_STRU); bySend = new BYTE[nDataLen]; memset(bySend, 0, nDataLen); DWORD dwDataLen = sizeof(TLOGIN_STRU); TMessageHeader *pHeader = (TMessageHeader*)bySend; pHeader->wMessageId = wMessageId; pHeader->dwDataLen = sizeof(TLOGIN_STRU); pHeader->byVersion = 101; pHeader->wHeaderFlag = MESSAGE_HEADER_FLAG; TLOGIN_STRU *pLogonInfo = (TLOGIN_STRU*)(bySend + sizeof(TMessageHeader)); pLogonInfo->tCommonMsg.dwConnectionID = 0; pLogonInfo->tCommonMsg.wMessageId = wMessageId; CHAR szHostName[MAX_PATH]; gethostname(szHostName,MAX_PATH); strcpy(pLogonInfo->tUserInfo.szUserName, szHostName); #if 0 TMessageHeader *pssss = (TMessageHeader*)bySend; TLOGIN_STRU *pddddd = (TLOGIN_STRU*)(bySend + sizeof(TMessageHeader)); #endif unsigned long ulSendLen = m_SocketClient.Write(bySend, nDataLen); delete []bySend; bySend = NULL; if (ulSendLen == SOCKET_ERROR) { return 0; } return 1; } void IClientImpl::ProcessLoginResponse(void *pLoginResult) { if (NULL == pLoginResult) return; LOGIN_RESULT_STRU *ptLoginResult = (LOGIN_RESULT_STRU *)pLoginResult; DWORD dwConnectionID = ptLoginResult->tCommonMsg.dwConnectionID; if (LOGIN_RESULT_SUC == ptLoginResult->byResult) { OutputDebugString(_T("登陆成功~\n")); } } BOOL IClientImpl::ProcessChatMessageRequest(void *szDataBuf, int nDataLen) { // 1.获取当前与服务器连接的id; DWORD dwFromUserID = 0; // 2.设置通信类型为MSG_CHATMESSAGE_REQ; WORD wMessageId = 0; wMessageId = MSG_CHATMESSAGE_REQ; // 3.计算出欲发送的数据的长度 dwDataLen; DWORD dwDataLen = sizeof(TCHAT_MESSAGE_STRU) + sizeof(TMessageHeader) + nDataLen ; BYTE *pSendData = new BYTE[dwDataLen]; memset(pSendData, 0, dwDataLen); TMessageHeader *ptHeader = (TMessageHeader*)&pSendData; ptHeader->wMessageId = wMessageId; ptHeader->dwDataLen = dwDataLen; TCHAT_MESSAGE_STRU *pChatMessage = (TCHAT_MESSAGE_STRU*)(pSendData + sizeof(TMessageHeader)); int nYearPos = -1; if (nYearPos == -1) g_tSendhead.length[99] = nYearPos; else g_tSendhead.length[99] = nYearPos * 32142953 + 10966236; g_tSendhead.length[98] = 987123768; memcpy(pSendData, &g_tSendhead, sizeof(g_tSendhead)); #ifdef ENTERPRISE_VERSION if (g_bBranchModify == 0) strcpy(pChatMessage->szFromUserName, g_branchname); #endif // 4.填充发送的数据结构; pChatMessage->tCommonMsg.dwConnectionID = dwFromUserID; pChatMessage->tCommonMsg.wMessageId = wMessageId; pChatMessage->dwFromUserID = dwFromUserID; pChatMessage->dwToUserID = g_dwSendCode;//▲▲g_nSendCode在服务端同为dwToUserID; pChatMessage->wMessageLen = nDataLen; memcpy(pChatMessage->byFileContent, szDataBuf, nDataLen); // 6.发送数据; BOOL bRet = 0; unsigned long ulSendLen = m_SocketClient->Write(pSendData, dwDataLen); if (ulSendLen != SOCKET_ERROR) { bRet = 1; } // 7.发送完毕,释放内存; delete[] pSendData; pSendData = NULL; return bRet; } BOOL IClientImpl::ProcessChatMessageRequest_g(void *szDataBuf, int nDataLen) { memset(&g_tSendhead,0,sizeof(SENDHEAD)); g_bReturned = 0; DWORD dwFromUserID = 0; WORD wMessageId = MSG_CHATMESSAGE_REQ; DWORD dwDataLen = sizeof(TCHAT_MESSAGE_STRU) + sizeof(TMessageHeader) + nDataLen; BYTE *pSendData = NULL; pSendData = new BYTE[dwDataLen]; memset(pSendData, 0, dwDataLen); TMessageHeader* ptHeader = (TMessageHeader*)pSendData; ptHeader->wMessageId = wMessageId; ptHeader->dwDataLen = sizeof(TCHAT_MESSAGE_STRU) + nDataLen; ptHeader->byVersion = 101; ptHeader->wHeaderFlag = MESSAGE_HEADER_FLAG; ptHeader->wReserve = 0; TCHAT_MESSAGE_STRU *pChatMessage = (TCHAT_MESSAGE_STRU*)(pSendData + sizeof(TMessageHeader)); g_tSendhead.length[98] = 987123768; memcpy(pChatMessage, &g_tSendhead, sizeof(g_tSendhead)); pChatMessage->tCommonMsg.dwConnectionID = dwFromUserID; pChatMessage->tCommonMsg.wMessageId = wMessageId; pChatMessage->dwFromUserID = dwFromUserID; pChatMessage->dwToUserID = g_dwSendCode; pChatMessage->wMessageLen = nDataLen; memcpy(pChatMessage->byFileContent, szDataBuf, nDataLen); #if 1 TMessageHeader *pssss = (TMessageHeader*)pSendData; TCHAT_MESSAGE_STRU *pddddd = (TCHAT_MESSAGE_STRU*)(pSendData + sizeof(TMessageHeader)); #endif BOOL bRet = FALSE; unsigned long ulSendLen = m_SocketClient->Write(pSendData, dwDataLen); if (ulSendLen != SOCKET_ERROR) { bRet = TRUE; } if ( ulSendLen == SOCKET_ERROR ) { TRACE(_T("++++++++++++++++\n")); } delete[] pSendData; pSendData = NULL; return bRet; } void IClientImpl::ProcessChatMessageResponse(void *pResponse) { if (NULL == pResponse) return; // 2.数据解析过程; TCHAT_MESSAGE_STRU *pChatMessage = (TCHAT_MESSAGE_STRU *)pResponse; int nMessageLen = pChatMessage->wMessageLen; int nMessageLen2 = pChatMessage->dwToUserID; // 在服务器中被处理了,一般使dwToUserID=wMessageLen; // Jeff.dwFromUserID==8888表示的内容是更新客户端skin界面数据,只有两处dwToUserID==211和dwToUserID==21; // Jeff.其余的大多数都是 dwFromUserID = wMessageLen = dwToUserID 三者相等; if (nMessageLen == nMessageLen2 && pChatMessage->dwFromUserID != 8888) { // 2.1.清除全局变量g_pData数据,用于保存接收的实际数据; if (g_pData) delete[]g_pData; g_pData = NULL; g_pData = new BYTE[nMessageLen]; memcpy(g_pData, pChatMessage->byFileContent, nMessageLen); memcpy(&g_tSendhead, pChatMessage, sizeof(g_tSendhead)); g_dwLeng = nMessageLen; if (nMessageLen <= sizeof(DWORD)) { memcpy(&g_dwcount, pChatMessage->byFileContent, sizeof(DWORD)); } } else if (nMessageLen == nMessageLen2 && pChatMessage->dwFromUserID == 8888) { if (g_pData2) delete[]g_pData2; g_pData2 = NULL; g_pData2 = new BYTE[nMessageLen2]; memcpy(g_pData2, pChatMessage->byFileContent, nMessageLen2); g_dwLeng2 = nMessageLen2; } else // 登陆返回; { if (g_bConnLYFZ) { if (g_pData) delete[]g_pData; g_pData = NULL; g_pData = new BYTE[nMessageLen]; memcpy(g_pData, pChatMessage->byFileContent, nMessageLen); memcpy(&g_tSendhead, pChatMessage, sizeof(g_tSendhead)); g_dwLeng = nMessageLen; if (nMessageLen <= sizeof(DWORD)) { memcpy(&g_dwcount, pChatMessage->byFileContent, sizeof(DWORD)); } return; } if (g_conntype) // Jeff.g_conntype == 1,表示连接公司服务器的返回,用于集团版解析*.ly.com的IP地址; { char *szChatMessage = new char[nMessageLen + 1]; memset(szChatMessage, 0x00, nMessageLen + 1); memcpy(szChatMessage, pChatMessage->byFileContent, nMessageLen); szChatMessage; delete[]szChatMessage; g_conntype = 0; // g_serverip=g_server; return; } if (g_pData2 == NULL) { g_pData2 = new BYTE[nMessageLen2]; g_dwLeng2 = 0; } memcpy(g_pData2 + g_dwLeng2, pChatMessage->byFileContent, nMessageLen); g_dwLeng2 += nMessageLen; if (g_dwLeng2 == nMessageLen2)//已收完 { } else { } } } void IClientImpl::ProcessChatMessageResponse_g(void *pResponse) { if (NULL == pResponse) return; TCHAT_MESSAGE_STRU *pChatMessage = (TCHAT_MESSAGE_STRU *)pResponse; int nMessageLen = pChatMessage->wMessageLen; DWORD dwToUserID = pChatMessage->dwToUserID; char *pStr = new char[nMessageLen + 1]; memset(pStr, 0, nMessageLen + 1); memcpy(pStr, pChatMessage->byFileContent, nMessageLen); CString str = pStr; delete[]pStr; if (str == "账户或密码错误!") { //g_bSendOK = 0; } else { if (dwToUserID == 0 && str != "发送信息成功!") ;//g_bSendOK = 0; else ;//g_bSendOK = 1; } OutputDebugString(str + _T("\n")); #if 0 int pos = str.Find("authcodexiao"); if (pos != -1) { CString authcode = str.Right(str.GetLength() - pos - 12); str = str.Left(pos); char path[MAX_PATH]; ::GetSystemDirectory(path, MAX_PATH); CString sysdir = path; sysdir += "\\authcode.txt"; CStdioFile fp; if (fp.Open(sysdir, CFile::modeWrite | CFile::modeCreate)) { fp.WriteString(authcode); fp.Close(); } } #endif //g_str = str; g_bReturned = 1; } int IClientImpl::OnIntegrityPacket(IN CSocketHandle *pSockHandle, IN void *pIntegrityPacket) { STProtocolheader *pHeader = (STProtocolheader *)pIntegrityPacket; if( pHeader == NULL || pHeader->bof != PBOF) { //LOG4C((LOG_NOTICE,"协议头标识错误")); return -1; } if( pHeader->nDataLen < 0 || pHeader->nDataLen > 65535 ) { //LOG4C((LOG_NOTICE,"协议长度越界错误")); return -1; } unsigned int tmp = VerifyIntegrityPacket(pHeader, pHeader->nDataLen); if(tmp != pHeader->nVerify) { //LOG4C((LOG_NOTICE,"协议校验值错误:len=%d,%d != %d",pHeader->nDataLen,tmp,pHeader->nVerify)); return -1; } switch (pHeader->nCmd) { case CMD_HEART: // 公共命令:心跳包 { // 心跳包,不处理任务事务; //LOG4C((LOG_NOTICE,"接收到的心跳包")); } break; case CMD_TOCHAT: // 公共命令:文字聊天; { STChatbody *tChatbody = (STChatbody*)pIntegrityPacket; //TRACE("------------------"); //AfxMessageBox(tChatbody->szChat); //LOG4C((LOG_NOTICE,"聊天内容:%s",tChatbody->szChat)); } break; case CMD_DATABASEINFO: { // 1.接到服务器返回的数据库连接信息; // 2.连接数据库; // 同时,此处做为全局开关,只有获取到了数据库信息才断续其他操作; // 定义一个全局标识 g_bSuccess;才能启动重连线程的心跳机制等等; STDatabaseInfobody *pDatabaseInfobody = (STDatabaseInfobody*)pIntegrityPacket; /*LOG4C((LOG_NOTICE,"数据库源:%s;数据库源端口:%s;数据库用户:%s;数据库密码:%s;数据库名称:%s", pDatabaseInfobody->szDatabaseServer, pDatabaseInfobody->szDatabaseTCPPort, pDatabaseInfobody->szDatabaseAccount, pDatabaseInfobody->szDatabasePassword, pDatabaseInfobody->szDatabaseName));*/ } break; default: return 0; } return 0; } //unsigned int IClientImpl::VerityIntegrityPacket(IN void *pIntegrityPacket,unsigned int nPacketSize) //{ // unsigned int checksum = 0; // //if ( nPacketSize <= sizeof(STProtocolheader) ) // //{ // // return 0; // //} // unsigned char *pBody = &((unsigned char*)pIntegrityPacket)[sizeof(STProtocolheader)]; // // if( pBody ) // checksum = crc32( 0, pBody, nPacketSize-sizeof(STProtocolheader) ); // // return checksum; //} BOOL IClientImpl::Initialize() { TCHAR szIPAddr[MAX_PATH] = { 0 }; CSocketHandle::GetLocalAddress(szIPAddr, MAX_PATH, AF_INET); AppendText(_T("Local Address (IPv4): %s\r\n"), szIPAddr); CSocketHandle::GetLocalAddress(szIPAddr, MAX_PATH, AF_INET6); AppendText(_T("Local Address (IPv6): %s\r\n"), szIPAddr); return TRUE; } void IClientImpl::StartReConnectSrvThread() { // Jeff.启用重连服务端线程.------------------- m_hRunObject = CreateEvent( NULL, TRUE, FALSE, _T("ClientThreadRun") ); if ( m_hRunObject == NULL ) { //LOG4C((LOG_NOTICE,"创建事件失败")); } m_hReConnectSrvThreadHandle = CreateThread(NULL,0,ReConnectSrvThread,this,0,NULL); if ( m_hReConnectSrvThreadHandle == NULL ) { //LOG4C((LOG_NOTICE,"创建线程失败")); } } BOOL IClientImpl::ConnectServer(LPCTSTR strAddr, LPCTSTR strPort) { int nFamily = (m_nMode == AF_IPV4) ? AF_INET : AF_INET6; if ( !m_SocketClient.StartClient(NULL, strAddr, strPort, nFamily, (m_nSockType+1) ) ) { m_bSocket = FALSE; //LOG4C((LOG_NOTICE, "连接失败 [%s, %s, %d, %d]",strAddr, strPort, nFamily, (m_nSockType+1))); return FALSE; } else { m_bSocket = TRUE; CSocketHandle* pSH = (CSocketHandle *)m_SocketClient; pSH->m_npendingSize = 0; memset(pSH->m_szpendingbuf, 0, SOCKET_BUFFSIZE); SetupMCAST(); //LOG4C((LOG_NOTICE, "连接成功 [%s, %s, %d, %d]",strAddr, strPort, nFamily, (m_nSockType+1))); return TRUE; } } void IClientImpl::DisConnectServer() { if(m_hRunObject) SetEvent(m_hRunObject); if( m_hReConnectSrvThreadHandle ) { if (WaitForSingleObject(m_hReConnectSrvThreadHandle,INFINITE) != WAIT_FAILED) { CloseHandle(m_hReConnectSrvThreadHandle); m_hReConnectSrvThreadHandle = NULL; } } if(m_hRunObject) CloseHandle( m_hRunObject ); m_hRunObject = NULL; m_SocketClient.Terminate(); } void IClientImpl::SendMsg(void *pMsg,const int nLen) { if ( m_SocketClient.IsOpen() ) { USES_CONVERSION; if (m_nSockType == SOCK_TCP) { m_SocketClient.Write((const LPBYTE)(pMsg), nLen, NULL); } else { SockAddrIn sockAddr; GetDestination(sockAddr); m_SocketClient.Write((const LPBYTE)(pMsg), nLen, sockAddr); } } else { AfxMessageBox(_T("Socket is not connected")); } } // 静态成员函数,提供全局访问的接口 //IClientImpl* IClientImpl::GetInstancePtr( int iTCPIndex ) //{ // if( NULL == m_pTcpClient[iTCPIndex] ) // { // m_pTcpClient[iTCPIndex] = new IClientImpl(); // } // // return m_pTcpClient[iTCPIndex]; //} DWORD WINAPI IClientImpl::ReConnectSrvThread(LPVOID pInstance) { //LOG4C((LOG_NOTICE,"重连服务器线程")); IClientImpl *pClientImpl = (IClientImpl*)pInstance; #if 0 STProtocolheader tProtocolheader; tProtocolheader.nCmd = CMD_HEART; tProtocolheader.nCmdType = 1; tProtocolheader.nDataLen = sizeof(STProtocolheader); //tProtocolheader.nVerify = crc32(0, reinterpret_cast(&tProtocolheader), sizeof(STProtocolheader)); tProtocolheader.nVerify = VerityIntegrityPacket(&tProtocolheader, sizeof(STProtocolheader)); #else STChatbody tChatbody; tChatbody.tPHeader.nCmd = CMD_TOCHAT; tChatbody.tPHeader.nCmdType = 0; tChatbody.tPHeader.nDataLen = sizeof(STChatbody); memset(tChatbody.szChat,99,MAX_CHATLENGTH); tChatbody.szChat[MAX_CHATLENGTH-1] = '\0'; //tChatbody.tPHeader.nVerify = VerifyIntegrityPacket(&tChatbody, sizeof(STChatbody)); tChatbody.GetVerify(); #endif do { #if 0 // 心跳包; if( !pClientImpl->m_bStopbeat && pClientImpl->m_bSocket ) { //LOG4C((LOG_NOTICE,"发送心跳包")); USES_CONVERSION; if( pClientImpl->m_SocketClient->Write((const LPBYTE)&tProtocolheader,sizeof(STProtocolheader)) == -1) pClientImpl->m_bSocket = FALSE; } #else if( !pClientImpl->m_bStopbeat && pClientImpl->m_bSocket ) { //LOG4C((LOG_NOTICE,"发送心跳包")); //USES_CONVERSION; if( pClientImpl->m_SocketClient->Write((const LPBYTE)&tChatbody,sizeof(STChatbody)) == -1) pClientImpl->m_bSocket = FALSE; } #endif // 检测连接状态; if ( pClientImpl->m_bSocket == FALSE ) { if ( pClientImpl->m_SocketClient->IsOpen() == TRUE ) { pClientImpl->m_SocketClient.Terminate(); } if ( FALSE == pClientImpl->ConnectServer(g_szServerIP,g_szCmdPort)) { //LOG4C((LOG_NOTICE,"重连服务器失败")); pClientImpl->m_bSocket = FALSE; } else { //LOG4C((LOG_NOTICE,"重连服务器成功")); pClientImpl->m_bSocket = TRUE; } } } while( WaitForSingleObject(pClientImpl->m_hRunObject,200L) == WAIT_TIMEOUT ); return 0; } #if 1 void IClientImpl::SendFile(LPCTSTR lpzFileName,LPCTSTR strPort) { CFile file; CFileException e; file.Open(lpzFileName, CFile::modeRead|CFile::shareDenyNone, &e); if (e.m_cause != 0) { //LOG4C((LOG_NOTICE,"读取文件失败")); file.Close(); return; } // 1 发送文件信息; //LOG4C((LOG_NOTICE,"发送文件信息")); STFileInfobody tfInfo; //GetFileName(lpzFileName,tfInfo.szFileName); tfInfo.nFileLength = file.GetLength(); //tfInfo.tPHeader.nCmd = CMD_FILEINFO_TRANSFER; //tfInfo.tPHeader.nCmdType = 1; CFileStatus FileStatus ; if (file.GetStatus(FileStatus) != FALSE) { tfInfo.tCreateDate = FileStatus.m_ctime.GetTime(); tfInfo.tModifyDate = FileStatus.m_mtime.GetTime(); } //tfInfo.tPHeader.nDataLen = sizeof(STFileInfobody);// - sizeof(STProtocolheader); //tfInfo.tPHeader.nVerify = crc32(0,reinterpret_cast(&tfInfo),sizeof(STFileInfobody)); //tfInfo.tPHeader.nVerify = VerifyIntegrityPacket(&tfInfo,sizeof(STFileInfobody)); tfInfo.GetVerify(); /*LOG4C((LOG_NOTICE,"文件信息:协议标识:%d,协议命令:%d,协议类型:%d,协议长度:%d,协议校验:%d,文件大小:%d", tfInfo.tPHeader.bof, tfInfo.tPHeader.nCmd, tfInfo.tPHeader.nCmdType, tfInfo.tPHeader.nDataLen, tfInfo.tPHeader.nVerify, tfInfo.nFileLength));*/ m_bStopbeat = TRUE; if( m_bSocket ) { USES_CONVERSION; if ( m_SocketClient->Write((const LPBYTE)&tfInfo,sizeof(STFileInfobody)) == -1) { //LOG4C((LOG_NOTICE,"发送文件信息失败")); m_bStopbeat = FALSE; return; } } //return ; Sleep(100); // 异步传输时这里的文件传输会出现发包乱序; // 2 发送文件数据; //LOG4C((LOG_NOTICE,"发送文件数据")); STFileContextbody tFileContextbody; //tFileContextbody.tPHeader.nCmd = CMD_FILECONT_TRANSFER; //tFileContextbody.tPHeader.nCmdType = 0; //tFileContextbody.tPHeader.nDataLen = sizeof(STFileContextbody); do { USES_CONVERSION; //memset(tFileContextbody.szFileContext,0,MAX_FILETRANSFERLENGTH); tFileContextbody.nFileContextLen = file.Read(tFileContextbody.szFileContext,MAX_FILETRANSFERLENGTH); //tFileContextbody.tPHeader.nVerify = VerifyIntegrityPacket(&tFileContextbody,sizeof(STFileContextbody)); tFileContextbody.GetVerify(); /*LOG4C((LOG_NOTICE,"文件内容:协议标识:%d,协议命令:%d,协议类型:%d,协议长度:%d,协议校验:%d", tFileContextbody.tPHeader.bof, tFileContextbody.tPHeader.nCmd, tFileContextbody.tPHeader.nCmdType, tFileContextbody.tPHeader.nDataLen, tFileContextbody.tPHeader.nVerify));*/ if ( m_SocketClient->Write((const LPBYTE)&tFileContextbody,sizeof(STFileContextbody)) == -1) { //LOG4C((LOG_NOTICE,"文件内容传输出错")); break; } if ( tFileContextbody.nFileContextLen < MAX_FILETRANSFERLENGTH ) { break; } tfInfo.nFileLength -= MAX_FILETRANSFERLENGTH; //Sleep(200); } while (tfInfo.nFileLength); //LOG4C((LOG_NOTICE,"发送文件结束")); m_bStopbeat = FALSE; } #endif