首页 / 软件开发 / C++ / 深入分析驴子系列(2)
深入分析驴子系列(2)2011-04-02 博客园 wangok在 BOOL CemuleApp::InitInstance() 函数 的 672行(VERIFY( (m_hTimer = ::SetTimer(NULL, NULL, 300, StartupTimer)) != NULL );) 启动一个定时器 在该定时器的 执行函数( void CALLBACK CemuleDlg::StartupTimer(HWND /*hwnd*/, UINT /*uiMsg*/, UINT /*idEvent*/, DWORD /*dwTime*/))的 814 行 theApp.emuledlg->OnBnClickedButton2();连接到emule服务器CServerSocket 就是一个客户端与服务器会话的类(或者说是服务器类),它连接某 一具体服务器 ,处理所有与此服务器有关的事物,比如(具体的)发数据,收数据,连 接到来等在连接到来的函数(void CServerSocket::OnConnect(int nErrorCode))里处理各种 情况(是否继续尝试连接)virtual void OnReceive(int nErrorCode) 函数里处理收到的数据包.由于连接比较复杂,所以专门封装了一个类 CServerConnect 来连接服务器。 CServerConnect驱动与多个服务器的连接,停止连接尝试,断开连接 ,对连接后的具体 信息的处理(如 连接正确 则发送 登陆消息,错误 则重新连接) 超时检测等此两个类 耦合性 较强,所以分析起来比较麻烦。比较好的情况是 只有导出耦合关系 ,一个类之引用另一个类另对两个类相关的有些函数可以分离出来形成一个新的类,这样职责比较单一异常: 对于 CServerConnect类 内部维持一个状态机(connecting 和connected 两 种状态)针对两种情况有不同处理,如为connecting 状态 则客户类 多次启动一个新连接对于 CServerSocket类,连接到来后 也有不同的情况 如果 正常 则发登陆消息,关 闭所有的与其它服务器的连接如果失败 则 要 CServerConnect 启动一个定时器 开始一个新的连接尝试连接服务器第一步:ConnectToAnyServer(UINT startAt, bool prioSort, bool isAuto, bool bNoCrypt) ;在该函数里 首先 停止 所有已经连接 和正在连接中的如果有静态服务器 则处理监听套接字启动监听tryAnotherConnectionRequest();// 启动连接正常情况下 在tryAnotherConnectionRequest函数里启动ConnectToServer(next_server, true, !m_bTryObfuscated);该函数真正实现一个与服务器连接,如果正在连接 则在CuploadQueue ::UploadTimer()函数的 965行if (theApp.serverconnect->IsConnecting())//如果正在连接则检查是否超时theApp.serverconnect->CheckForTimeout(); //一秒钟以后检查连接是否超时检查是否连接超时如果 已经连接进去或者 服务器等待登陆信息 则发送登陆信息当正在连接时,客户端会等待 连接事件发生void CServerSocket::OnConnect(int nErrorCode)在该函数里处理各种连接事件,如果正常的话 则发登陆消息 不正常的话 则重新启动 与其它服务器连接异常情况 处理函数void CServerConnect::ConnectionFailed(CServerSocket* sender)驴子连接服务器的过程写的比较细腻,主要有两个类CServerSocket, CServerConnect 来完成服务器的连接与通讯在 BOOL CemuleApp::InitInstance() 函数 的 672行(VERIFY( (m_hTimer = ::SetTimer(NULL, NULL, 300, StartupTimer)) != NULL );) 启动一个定时器 在该定时器的 执行函数( void CALLBACK CemuleDlg::StartupTimer(HWND /*hwnd*/, UINT /*uiMsg*/, UINT /*idEvent*/, DWORD /*dwTime*/))的 814 行 theApp.emuledlg->OnBnClickedButton2();连接到emule服务器登陆服务器以上基本完成了服务器连接的过程