在 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服務器
登陸服務器
以上基本完成了服務器連接的過程