基于WinSocket的網絡通信實現
發表于:2007-07-14來源:作者:點擊數:
標簽:
陳廣奕 VC++中,MFC編程支持兩種利用 Windows Sockets進行 網絡 通信的編程模式,這兩種模式即為用CAsyncSocket類和派生于CAsyncSocket 的CSocket類。 * CAsyncSocket類封裝了Windows Sockets API函數,提供了較低層的與Windows Sockets對話接口,一般適
陳廣奕
VC++中,MFC編程支持兩種利用
Windows Sockets進行
網絡通信的編程模式,這兩種模式即為用CAsyncSocket類和派生于CAsyncSocket 的CSocket類。
?。?CAsyncSocket類封裝了Windows Sockets API函數,提供了較低層的與Windows Sockets對話接口,一般適合于有相當水平的網絡編程基礎者使用,可方便地進行底層的網絡事件通知及信息回叫控制等操作。
?。?CSocket派生于CAsyncSocket,它繼承了父類中一些常用易懂得的Windows Sockets API函數,并對CAsyncSocket中底層的較難控制的一些API函數或成員函數進行了處理,它通過MFC CArchive 對象進行信息的接發操作,使得網絡傳輸如同使用MFC的文檔連載協議(Serialization protocol),簡捷易用。同時它支持模塊化的后臺信息處理,解決了CAsyncSocket中較難克服的多線程處理。
Socket的建立與使用操作
作為
服務器,需要有一專用于接聽的Socket,以便于隨時接收從客戶發送來的信息,CSocket類的Listen本身支持多線程,故而不必為其開辟新的線程。建立Windows Sockets的操作步驟見表1。
?服務器Socket的建立與使用
?。?在服務器應用程序中聲名Socket全局變量,并使其處于聽等狀態以等待客戶端與其建立連接:
CListeningSocket? m—pSocket;
m—pSocket = new CListeningSocket(this);
if (m—pSocket-〉Create(Dialog.m—nPort+700))
{ if (m—pSocket-〉Listen())
return TRUE;
}
?。?當接到客戶端的主動連接時或接到數據時,調用文檔類接收新客戶的處理函數:
void CListeningSocket::OnA
clearcase/" target="_blank" >ccept(int nErrorCode)
{ CSocket::OnAccept(nErrorCode);
m—pDoc-〉ProcessPendingAccept(); //調用文檔類成員函數,以生成新的對話線程
}
?。?服務器Socket的網上數據發送與接收操作:
void
CClientSocket::SendMsg(CMsg? pMsg)
{ if (m—pArchiveOut != NULL)
{ pMsg-〉Serialize(?m—pArchiveOut);
//調用按協議自定義信息類(CMsg)的函數
m—pArchiveOut-〉Flush();
//Serialize進行網上信息發送操作
} }
void CClientSocket::ReceiveMsg(CMsg? pMsg)
{ pMsg-〉Serialize(?m—pArchiveIn); } //調用按協議自定義信息類(CMsg)的函數
//Serialize進行網上信息接收操作
客戶端建立連接與通信實現
?。?新客戶與服務器端建立連接:
BOOL CChatDoc::ConnectSocket(LPCTSTR lpszHandle, LPCTSTR lpszAddress, UINT nPort)
{ m—strHandle = lpszHandle;
m—pSocket = new CChatSocket(this);
if (!m—pSocket-〉Create())
{...} // 創建新Socket失敗處理
while (!m—pSocket-〉Connect(lpszAddress, nPort + 700))
{...} //與服務器建立連接失敗后的處理
m—pFile = new CSocketFile(m—pSocket);
m—pArchiveIn = new CArchive(m—pFile,CArchive::load);
m—pArchiveOut = new CArchive(m—pFile,CArchive::store);// 建立通信流對象
return TRUE; }
?。?客戶端從流中讀入網上信息:
void CChatDoc::ReceiveMsg()
{ CMsg msg;
TRY { msg.Serialize(?m—pArchiveIn);
//調用按協議自定義信息類(CMsg)的函數
while(!msg.m—msgList.IsEmpty()) //Serialize進行網上信息接收操作
{...
CATCH(CFileException, e) {... } END—CATCH // 出錯處理
if (msg.m—bClose)
{...} // 關閉連接的善后處理
}
?。?客戶端通過流進行網上發送信息:
void CChatDoc::SendMsg(CString& strText,int index,int i)
{ if (m—pArchiveOut != NULL)
{ CMsg ?msg;
msg=AssembleMsg(index,i);
// 裝配信息
TRY { msg-〉Serialize(?m—pArchiveOut); //調用按協議自定義信息類(CMsg)的函數
m—pArchiveOut-〉Flush();
// Serialize進行網上信息發送操作
}
CATCH(CFileException, e)
{ ...... } // 出錯處理
END—CATCH
}
}
表1
服務器端 注釋 客戶端
1 csocket socksrvr; 構造一個socket對象 csocket sockclient;
2 socksrvr.create(nport); 創建socket sockclient.create(nport);
3 socksrvr.listen(); 聽等
連接 與服務器
建立連接 sockclient.connect
(straddr,nport);
4 csocket sockrecv;
socksrvr.accept(sockrecv); 構造新的socket對象用以接收客戶端的連接
5 csocketfile file(&sockrecv); 構造一文件對象 csocketfile file
(&sockrecv);
6 carchive arin
(&file,carchive::load);
carchive arout
(&file,carchive::store); 構造流對象 carchive arin
(&file,carchive::load);
carchive arout
(&file,carchive::store);
7 arin〉〉dwvalue;
arout〈〈dwvalue; 用流進行數據的傳輸 arin〉〉dwvalue;
arout〈〈dwvalue;
原文轉自:http://www.anti-gravitydesign.com