目錄
概述
一.MFC Winsock 類簡介
1.MFC Winsock 類的主要功能
2.MFC Winsock 類的主要優點
3.MFC Winsock 類的主要缺點
4.MFC Winsock 類的主要類
5.MFC Winsock 類示例
二.CAsyncSocket 類
1.主要功能
異步通信
事件驅動
數據傳輸
套接字選項
2.常用函數
創建套接字對象
連接到遠程服務器
發送和接收數據
關閉套接字連接
處理網絡事件的函數
三.CSocket 類
1.CSocket類的特點
2.主要功能
3.常用函數
四.MFC Winsock 編程模型
1.基于事件的編程模型
2.基于同步的編程模型
總結
概述
????????MFC(Microsoft Foundation Class)是 Microsoft 公司提供的一套 C++ 類庫,用于在 Windows 平臺上開發桌面應用程序。MFC 提供了豐富的類和函數,簡化了 Windows 應用程序的開發。除了用于開發傳統 GUI 應用程序的類之外,MFC 還提供了用于網絡編程的類,稱為 MFC Winsock 類。
一.MFC Winsock 類簡介
????????MFC Winsock 類是 MFC 框架中用于網絡編程的一套類,它封裝了 Windows 操作系統中的 Winsock API(Windows Sockets API),為程序員提供了一套面向對象的接口來實現網絡通信和數據傳輸。MFC Winsock 類簡化了網絡編程的過程,使程序員能夠更容易地開發網絡應用程序。
1.MFC Winsock 類的主要功能
- 建立和管理網絡連接
- 發送和接收網絡數據
- 處理網絡事件
2.MFC Winsock 類的主要優點
- 面向對象,易于使用
- 封裝了 Winsock API 的復雜性
- 提供了豐富的功能和工具
3.MFC Winsock 類的主要缺點
- 執行效率較低
- 增加了代碼量
4.MFC Winsock 類的主要類
- CSocket 類:用于建立和管理網絡連接。
- CAsyncSocket 類:用于異步網絡通信。
- CArchive 類:用于序列化和反序列化網絡數據。
5.MFC Winsock 類示例
以下代碼演示了如何使用 MFC Winsock 類建立一個 TCP 連接并發送數據:
CSocket socket;// 建立連接
socket.Create();
socket.Connect(_T("127.0.0.1"), 80);// 發送數據
CString strData = _T("Hello, World!");
socket.Send(strData.GetBuffer(), strData.GetLength());// 關閉連接
socket.Close();
二.CAsyncSocket 類
????????CAsyncSocket 類是 MFC Winsock 類庫中的一個重要類,它提供了一個異步套接字對象,用于實現異步網絡通信。異步套接字允許應用程序在發送或接收數據時不阻塞,從而提高了應用程序的響應能力。
1.主要功能
????????CAsyncSocket類是MFC框架中用于異步網絡編程的核心類,它封裝了Windows Sockets API中的異步網絡編程功能,為程序員提供了一套面向對象的接口來實現異步網絡通信和數據傳輸。CAsyncSocket類具有以下主要功能:
異步通信
????????CAsyncSocket類支持異步通信,這意味著應用程序在發送或接收數據時不阻塞,可以繼續執行其他任務。這使得應用程序能夠提高響應速度和處理效率,尤其是在需要同時處理多個網絡連接的情況下。
CAsyncSocket類提供了以下異步通信功能:
- 異步連接:應用程序可以使用CAsyncSocket類的Connect函數異步地建立網絡連接。在連接建立完成后,CAsyncSocket類會觸發一個連接事件通知應用程序。
- 異步發送:應用程序可以使用CAsyncSocket類的Send函數異步地發送數據。在數據發送完成后,CAsyncSocket類會觸發一個發送事件通知應用程序。
- 異步接收:應用程序可以使用CAsyncSocket類的Receive函數異步地接收數據。在數據接收完成后,CAsyncSocket類會觸發一個接收事件通知應用程序。
事件驅動
????????CAsyncSocket類采用事件驅動機制來通知應用程序網絡事件的發生。應用程序可以注冊事件處理函數來響應CAsyncSocket類觸發的各種事件,例如連接建立、數據接收、連接關閉等。
CAsyncSocket類支持以下事件:
- 連接事件:連接建立時觸發,通知應用程序連接已建立。
- 發送事件:數據發送完成后觸發,通知應用程序數據已發送。
- 接收事件:數據接收完成后觸發,通知應用程序數據已接收。
- 錯誤事件:發生錯誤時觸發,通知應用程序錯誤信息。
- 關閉事件:連接關閉時觸發,通知應用程序連接已關閉。
數據傳輸
????????CAsyncSocket類提供了發送和接收數據的函數,應用程序可以發送或接收文本或二進制數據。
CAsyncSocket類支持以下數據傳輸功能:
- 發送文本數據:應用程序可以使用CAsyncSocket類的SendString函數發送文本數據。
- 發送二進制數據:應用程序可以使用CAsyncSocket類的Send函數發送二進制數據。
- 接收文本數據:應用程序可以使用CAsyncSocket類的ReceiveString函數接收文本數據。
- 接收二進制數據:應用程序可以使用CAsyncSocket類的Receive函數接收二進制數據。
套接字選項
????????CAsyncSocket類提供了設置或獲取套接字選項的函數,如超時時間、緩沖區大小等。套接字選項可以控制網絡連接的行為和性能。
CAsyncSocket類支持以下套接字選項:
- 超時時間:設置或獲取連接超時時間和接收超時時間。
- 緩沖區大小:設置或獲取發送緩沖區大小和接收緩沖區大小。
- 重傳策略:設置或獲取數據重傳策略。
2.常用函數
????????CAsyncSocket類是MFC框架中用于異步網絡編程的核心類,它提供了豐富的函數來實現異步網絡通信和數據傳輸。以下是一些CAsyncSocket類的常用函數:
創建套接字對象
Create()
:創建一個異步套接字對象。
CAsyncSocket socket;// 創建套接字對象
socket.Create();
連接到遠程服務器
Connect()
:連接到一個遠程服務器。
// 連接到遠程服務器
socket.Connect(_T("127.0.0.1"), 80);
發送和接收數據
Send()
:發送數據。Receive()
:接收數據。
// 發送文本數據
CString strData = _T("Hello, World!");
socket.Send(strData.GetBuffer(), strData.GetLength());// 接收文本數據
CString strRecv;
int nRecv = socket.Receive(strRecv.GetBuffer(), strRecv.GetBufferSize());
strRecv.ReleaseBuffer(nRecv);
關閉套接字連接
Close()
:關閉套接字連接。
// 關閉套接字連接
socket.Close();
處理網絡事件的函數
CAsyncSocket類支持以下網絡事件:
- 連接事件:連接建立時觸發,通知應用程序連接已建立。
- 發送事件:數據發送完成后觸發,通知應用程序數據已發送。
- 接收事件:數據接收完成后觸發,通知應用程序數據已接收。
- 錯誤事件:發生錯誤時觸發,通知應用程序錯誤信息。
- 關閉事件:連接關閉時觸發,通知應用程序連接已關閉。
????????應用程序可以注冊事件處理函數來響應CAsyncSocket類觸發的各種事件。以下是一些常用的事件處理函數:
OnConnect()
:處理連接事件。OnSend()
:處理發送事件。OnReceive()
:處理接收事件。OnError()
:處理錯誤事件。OnClose()
:處理關閉事件。
例如,以下代碼演示了如何注冊事件處理函數:
socket.SetEventMask(FM_CONNECT | FM_SEND | FM_RECEIVE | FM_CLOSE | FM_ERROR
);socket.AttachWindow(this);
三.CSocket 類
????????CSocket類是MFC Winsock類庫中的重要成員,它提供了一個同步套接字對象,用于實現同步網絡通信。與異步套接字(CAsyncSocket)不同,CSocket在進行數據發送或接收時會阻塞主線程,直到操作完成或超時。
1.CSocket類的特點
- 同步操作:CSocket的Send和Receive函數是阻塞式的,會在數據發送或接收完成或超時之前一直占用主線程。
- 面向對象封裝:CSocket封裝了底層的Winsock API,為開發人員提供了更加直觀易用的面向對象接口。
- 便捷的數據管理:CSocket可以與CSocketFile和CArchive類協同工作,簡化數據的發送和接收操作。
2.主要功能
????????CSocket類是MFC框架中提供的一個用于網絡編程的類,它封裝了Windows Socket API,為開發人員提供了一個面向對象的編程接口。CSocket類的主要功能包括:
1. 同步通信
????????CSocket類提供了同步的發送和接收數據函數,即Send
和Receive
函數。在調用Send
函數時,應用程序會阻塞等待數據發送完成,直到所有數據都被發送或發生錯誤為止。在調用Receive
函數時,應用程序也會阻塞等待數據接收完成,直到接收指定數量的數據或發生錯誤為止。
????????同步通信模式適用于需要保證數據傳輸可靠性的場景,例如文件傳輸、關鍵數據的傳輸等。
2. 數據傳輸
????????CSocket類提供了發送和接收文本或二進制數據的函數,即SendText
、ReceiveText
、SendBuffer
和ReceiveBuffer
函數。SendText
和ReceiveText
函數用于發送和接收文本數據,SendBuffer
和ReceiveBuffer
函數用于發送和接收二進制數據。
????????CSocket類支持多種數據格式的轉換,包括文本格式(ANSI、Unicode)、二進制格式等。
3. 套接字選項
????????CSocket類提供了設置或獲取套接字選項的函數,即SetSocketOption
和GetSocketOption
函數。套接字選項用于控制套接字的行為,例如設置超時時間、緩沖區大小、重傳策略等。
????????設置合理的套接字選項可以提高網絡通信的效率和可靠性。
4. 異常處理
????????CSocket類提供了異常處理機制,當發生網絡錯誤時會拋出異常,例如CNetworkException
、CTimeoutException
等。程序員可以捕獲這些異常并進行相應的處理。
????????異常處理機制可以簡化網絡編程的代碼,提高程序的魯棒性。
3.常用函數
????????CSocket類提供了豐富的函數來滿足各種網絡編程需求,以下是一些常用的函數及其說明:
1. Create()
功能:創建一個同步套接字對象。
語法:
BOOL Create(AF_INET af, int type, int protocol);
參數說明:
af
:地址家族,指定套接字使用的地址類型,例如AF_INET
表示IPv4地址,AF_INET6
表示IPv6地址。type
:套接字類型,例如SOCK_STREAM
表示面向連接的套接字,SOCK_DGRAM
表示無連接的套接字。protocol
:協議類型,指定套接字使用的協議,例如IPPROTO_TCP
表示TCP協議,IPPROTO_UDP
表示UDP協議。
返回值:
- 成功創建套接字返回TRUE,失敗返回FALSE。
示例代碼:
CSocket socket;// 創建一個IPv4、面向連接、使用TCP協議的套接字
BOOL bRet = socket.Create(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (!bRet)
{AfxMessageBox(_T("Create socket failed!"));return;
}
2. Connect()
功能:連接到一個遠程服務器。
語法:
BOOL Connect(LPCTSTR lpszAddress, UINT nPort);
參數說明:
lpszAddress
:遠程服務器的地址,可以是域名或IP地址。nPort
:遠程服務器的端口號。
返回值:
- 成功連接返回TRUE,失敗返回FALSE。
示例代碼:
CSocket socket;// 創建一個套接字
socket.Create(AF_INET, SOCK_STREAM, IPPROTO_TCP);// 連接到服務器
BOOL bRet = socket.Connect(_T("127.0.0.1"), 80);
if (!bRet)
{AfxMessageBox(_T("Connect to server failed!"));return;
}
3. Send()?和?Receive()
功能:發送和接收數據。
語法:
int Send(LPVOID lpBuffer, int nBufferLen);
int Receive(LPVOID lpBuffer, int nBufferLen);
參數說明:
lpBuffer
:指向要發送或接收數據的緩沖區的指針。nBufferLen
:緩沖區的大小。
返回值:
- 發送或接收的數據字節數,如果發生錯誤則返回-1。
示例代碼:
CSocket socket;// 創建一個套接字
socket.Create(AF_INET, SOCK_STREAM, IPPROTO_TCP);// 連接到服務器
socket.Connect(_T("127.0.0.1"), 80);// 發送數據
CString data = _T("Hello, World!");
int nSendBytes = socket.Send(data.GetBuffer(), data.GetLength());
if (nSendBytes == -1)
{AfxMessageBox(_T("Send data failed!"));return;
}// 接收數據
char buffer[1024];
int nRecvBytes = socket.Receive(buffer, sizeof(buffer));
if (nRecvBytes == -1)
{AfxMessageBox(_T("Receive data failed!"));return;
}// 處理接收到的數據
CString receivedData(buffer, nRecvBytes);
AfxMessageBox(receivedData);
4. Close()
功能:關閉套接字連接。
語法:
void Close();
?示例代碼:
CSocket socket;// 創建一個套接字
socket.Create(AF_INET, SOCK_STREAM, IPPROTO_TCP);// 連接到服務器
socket.Connect(_T("127.0.0.1"), 80);// 發送數據
CString data = _T("Hello, World!");
int nSendBytes = socket.Send(data.GetBuffer(), data.GetLength());
if (nSendBytes == -1)
{AfxMessageBox(_T("Send data failed!"));return;
}// 接收數據
char buffer[1024];
int nRecvBytes = socket.Receive(buffer, sizeof(buffer));
if (nRecvBytes == -1)
{AfxMessageBox(_T("Receive data failed!"));
四.MFC Winsock 編程模型
????????MFC Winsock 類庫提供了兩種主要的編程模型:基于事件的編程模型和基于同步的編程模型。
1.基于事件的編程模型
????????CAsyncSocket類除了支持同步通信外,還支持基于事件的異步通信。在異步通信模式下,應用程序在發送或接收數據時不會阻塞,而是繼續執行其他操作。當網絡事件發生時,MFC框架會調用應用程序指定的事件處理函數,應用程序可以在其中處理事件。
基于事件的編程模型具有以下優點:
- 提高了應用程序的響應能力。應用程序在發送或接收數據時不會阻塞,可以繼續執行其他操作,從而提高了應用程序的響應速度。
- 降低了對CPU資源的占用。由于應用程序在等待網絡事件時不會占用CPU資源,因此可以提高CPU資源的利用率。
- 簡化了程序的編寫。基于事件的編程模型使用事件處理函數來處理網絡事件,可以簡化程序的編寫。
以下是一些使用CAsyncSocket類進行異步網絡編程的示例代碼:
class CMySocket : public CSocket
{
public:CMySocket(){m_pWnd = NULL;}~CMySocket(){m_pWnd = NULL;}DECLARE_DYNAMIC(CMySocket)public:virtual void OnReceive(int nErrorCode, int nBytesTransfered, LPVOID lpBuffer){if (nErrorCode == 0){CString strData((char*)lpBuffer, nBytesTransfered);m_pWnd->PostMessage(WM_SOCKET_DATA, nBytesTransfered, (LPARAM)strData.GetBuffer());}else{AfxMessageBox(_T("Receive data failed!"));}}virtual void OnConnect(int nErrorCode){if (nErrorCode == 0){AfxMessageBox(_T("Connect to server successfully!"));}else{AfxMessageBox(_T("Connect to server failed!"));}}private:CWnd* m_pWnd;
};class CMyDlg : public CDialog
{
public:CMyDlg(CWnd* pParent = NULL) : CDialog(CMyDlg::IDD, pParent){}enum { IDD = IDD_MYDLG };protected:virtual void OnInitDialog(){CDialog::OnInitDialog();m_socket.Create(AF_INET, SOCK_STREAM, IPPROTO_TCP);m_socket.SetEventHandler(&m_socketEventHandler);}virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam){if (wParam == ID_CONNECT){BOOL bRet = m_socket.Connect(_T("127.0.0.1"), 80);if (!bRet){AfxMessageBox(_T("Connect to server failed!"));return FALSE;}}else if (wParam == ID_SEND){CString data = _T("Hello, World!");int nSendBytes = m_socket.Send(data.GetBuffer(), data.GetLength());if (nSendBytes == -1){AfxMessageBox(_T("Send data failed!"));return FALSE;}}return TRUE;}private:CMySocket m_socket;CMySocketEventHandler m_socketEventHandler;
};class CMySocketEventHandler : public CAsyncSocketEventHandler
{
public:CMySocketEventHandler(){m_pDlg = NULL;}~CMySocketEventHandler(){m_pDlg = NULL;}void SetDlg(CMyDlg* pDlg){m_pDlg = pDlg;}public:virtual void OnReceive(int nErrorCode, int nBytesTransfered, LPVOID lpBuffer){if (m_pDlg){m_pDlg->PostMessage(WM_SOCKET_DATA, nBytesTransfered, (LPARAM)lpBuffer);}}virtual void OnConnect(int nErrorCode){if (m_pDlg){if (nErrorCode == 0){m_pDlg->PostMessage(WM_SOCKET_CONNECT,
2.基于同步的編程模型
????????基于同步的編程模型使用CSocket類實現同步網絡通信。應用程序創建一個同步套接字對象,并調用同步的發送和接收數據函數。這些函數在操作完成或超時之前是阻塞的。這意味著應用程序在調用這些函數時會一直等待,直到數據發送或接收完成,或者發生錯誤為止。
基于同步的編程模型具有以下優點:
- 簡化了網絡編程的過程。同步的發送和接收數據函數使用起來非常簡單,應用程序只需調用這些函數并等待結果即可。
- 保證了數據完整性和順序。由于同步的發送和接收數據函數是阻塞的,因此可以保證數據完整性和順序。
但是,基于同步的編程模型也存在以下缺點:
- 降低了應用程序的響應能力。由于應用程序在發送或接收數據時會阻塞,因此會降低應用程序的響應能力。
- 占用CPU資源。由于應用程序在等待網絡事件時會占用CPU資源,因此會降低CPU資源的利用率。
以下是一些使用CSocket類進行同步網絡編程的示例代碼:
CSocket socket;// 創建一個套接字
socket.Create(AF_INET, SOCK_STREAM, IPPROTO_TCP);// 連接到服務器
socket.Connect(_T("127.0.0.1"), 80);// 發送數據
CString data = _T("Hello, World!");
int nSendBytes = socket.Send(data.GetBuffer(), data.GetLength());
if (nSendBytes == -1)
{AfxMessageBox(_T("Send data failed!"));return;
}// 接收數據
char buffer[1024];
int nRecvBytes = socket.Receive(buffer, sizeof(buffer));
if (nRecvBytes == -1)
{AfxMessageBox(_T("Receive data failed!"));return;
}// 處理接收到的數據
CString receivedData(buffer, nRecvBytes);
AfxMessageBox(receivedData);
總結
????????MFC Winsock 類是 MFC 框架中用于網絡編程的一套類,它封裝了 Windows 操作系統中的 Winsock API,為程序員提供了一套面向對象的接口來實現網絡通信和數據傳輸。MFC Winsock 類庫提供了異步和同步兩種編程模型,滿足了不同應用程序的需求。MFC Winsock 類廣泛應用于各種 Windows 網絡應用程序中,為程序員提供了強大的工具和框架,簡化了網絡編程的過程。