// ClientTestDlg.cpp : 实现文件 // #include "stdafx.h" #include "ClientTest.h" #include "ClientTestDlg.h" #include "struct_def.h" #include "msgId_def.h" #include "lzari.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // typedef struct // { // BYTE bsql; // BYTE tabcount; // BYTE code[100]; // DWORD count[100]; // DWORD length[100]; // }SENDHEAD; BOOL g_bSendOK = FALSE; BYTE* g_pData2 = NULL; BYTE *g_pData = NULL; SENDHEAD g_sendhead; DWORD g_nLeng = 0; DWORD g_nLeng2 = 0; DWORD g_ncount = 0; static void HandleClientNetEvent(IN SOCKET hSocket, IN ETransportEvent eEvent, IN void *pDataBuf, IN unsigned long nDataLen, IN int nError, IN void *pContext); // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialog { public: CAboutDlg(); // 对话框数据 enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() // CClientTestDlg 对话框 CClientTestDlg::CClientTestDlg(CWnd* pParent /*=NULL*/) : CDialog(CClientTestDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_bIsConnected = FALSE; m_bIsLogined = FALSE; } void CClientTestDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CClientTestDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_DESTROY() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_BN_CLICKED(IDOK, &CClientTestDlg::OnBnClickedOk) ON_BN_CLICKED(IDCANCEL, &CClientTestDlg::OnBnClickedCancel) ON_BN_CLICKED(IDC_BUTTON2, &CClientTestDlg::OnBnClickedButton2) ON_BN_CLICKED(IDC_BUTTON3, &CClientTestDlg::OnBnClickedButton3) END_MESSAGE_MAP() // CClientTestDlg 消息处理程序 BOOL CClientTestDlg::OnInitDialog() { CDialog::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } m_tClientTunnel.Transport_Init(); // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } void CClientTestDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CClientTestDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR CClientTestDlg::OnQueryDragIcon() { return static_cast(m_hIcon); } void CClientTestDlg::OnDestroy() { if (g_pData) delete[]g_pData; g_pData = NULL; CClientTunnel::Transport_UnInit(); } static void HandleClientNetEvent(IN SOCKET hSocket, IN ETransportEvent eEvent, IN void *pDataBuf, IN unsigned long nDataLen, IN int nError, IN void *pContext) { if (nError != TRANSPORT_OK) return; CClientTestDlg *pDlg = (CClientTestDlg *)pContext; if (NULL == pDlg) return; pDlg->ProcessNetEvent(eEvent, pDataBuf, nDataLen); } void CClientTestDlg::ProcessNetEvent(int nEventType, void *pRecvMsg, DWORD dwDataLen) { if (Transport_ReadEv == nEventType) { if (NULL == pRecvMsg) return; TMessageHeader* pHeader = (TMessageHeader *)pRecvMsg; char *pDataBuf = (char *)pRecvMsg + 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 5: { break; } case 3: { break; } case MSG_CHATMESSAGE_RESP: case (MSG_CHATMESSAGE_RESP + 0X4FFF): { TCHAT_MESSAGE_STRU *pChatMessage = (TCHAT_MESSAGE_STRU *)pDataBuf; ProcessChatMessageResponse((void *)pChatMessage); } default: { break; } } } else if (Transport_CloseEv == nEventType) { // OnDisconnect(); } } //登录返回 void CClientTestDlg::ProcessLoginResponse(void *pLoginResult) { if (NULL == pLoginResult) return; LOGIN_RESULT_STRU *ptLoginResult = (LOGIN_RESULT_STRU *)pLoginResult; DWORD dwConnectionID = ptLoginResult->tCommonMsg.dwConnectionID; BYTE byResult = ptLoginResult->byResult; if (LOGIN_RESULT_SUC == byResult) { m_bIsLogined = TRUE; OutputDebugString(_T("登录成功\n")); } else OutputDebugString(_T("登录失败\n")); } //边接服务器 void CClientTestDlg::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码 int nResult = m_tClientTunnel.net_OpenSocket( Transport_Client, 0, HandleClientNetEvent, this); if (TRANSPORT_OK != nResult) { MessageBox(_T("网络初始化失败!")); return; } unsigned long ulIPValue = inet_addr("127.0.0.1"); unsigned short usPort = 643200; //if(m_tClientTunnel.net_Connect(ulIPValue, usPort) == -1) if( !m_tClientTunnel.net_Connect("192.168.1.191", "643200") ) { MessageBox(_T("连接失败!")); return; } ((CButton*)GetDlgItem(IDOK))->EnableWindow(FALSE); m_bIsConnected = TRUE; } void CClientTestDlg::ProcessChatMessageResponse(void *pResponse) { //printf("Jeff:ProcessChatMessageResponse**************\n\n");//Jeff Printf; // 1.数据空,直接返回; if (NULL == pResponse) return; // 2.数据解析过程; //printf("Jeff:ProcessChatMessageResponse**************\数据解析过程\n\n");//Jeff Printf; 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_sendhead, pChatMessage, sizeof(g_sendhead)); g_nLeng = nMessageLen; if (nMessageLen <= sizeof(DWORD)) memcpy(&g_ncount, 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_nLeng2 = nMessageLen2; } else { //登录返回 OutputDebugString(_T("登录返回\n")); return; } if(g_pData != NULL ) //&& _tcscmp((char*)g_pData, _T("")) != 0) { CArray AryList; DataToArray( g_pData, g_nLeng, &AryList); for(int i=0; i* List1array) { List1array->RemoveAll(); if (dwLength == 0)return; if (g_sendhead.code[0]) { BYTE *lpszOut = NULL; int nOutSize = 0; LZARI Lzari; Lzari.UnCompress(pData, dwLength, (const BYTE*&)lpszOut, nOutSize); CMemFile memfile; memfile.Attach(lpszOut, nOutSize); Lzari.Release(); try { CArchive ar(&memfile, CArchive::load); List1array->SetSize(g_sendhead.count[0]); for (int i = 0; i < List1array->GetSize(); i++) { List1array->ElementAt(i).Serialize(ar); } ar.Close(); memfile.Detach(); } catch (CException* e) { e->ReportError(); } } else { CMemFile memfile; memfile.Attach(pData, dwLength); CArchive ar(&memfile, CArchive::load); List1array->SetSize(g_sendhead.count[0]); for (int ii = 0; ii < List1array->GetSize(); ii++) List1array->ElementAt(ii).Serialize(ar); ar.Close(); memfile.Detach(); } } //发送数据 BOOL CClientTestDlg::ProcessChatMessageRequest(void *szDataBuf, int nDataLen) { BOOL bRecevie = FALSE; DWORD dwFromUserID = 0; WORD wMessageId = MSG_CHATMESSAGE_REQ + 0X3FFF; 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_sendhead.length[98] = 987123768; memcpy(pChatMessage, &g_sendhead, sizeof(g_sendhead)); pChatMessage->tCommonMsg.dwConnectionID = dwFromUserID; pChatMessage->tCommonMsg.wMessageId = wMessageId; pChatMessage->dwFromUserID = dwFromUserID; pChatMessage->dwToUserID = 15; pChatMessage->wMessageLen = nDataLen; memcpy(pChatMessage->byFileContent, szDataBuf, nDataLen); // 6.发送数据; BOOL bRet = 0; unsigned long ulSendLen = m_tClientTunnel.net_Send(ptHeader, (void *)pChatMessage, dwDataLen); if (ulSendLen != SOCKET_ERROR) bRet = 1; // 7.发送完毕,释放内存; delete[] pSendData; g_bSendOK = TRUE; return bRet; }