精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

網(wǎng)絡(luò)安全編程:非阻塞模式開發(fā)

安全
Winsock套接字的工作模式有兩種,分別是阻塞模式(同步模式)和非阻塞模式(異步模式)。阻塞模式下的Winsock函數(shù)會(huì)將程序的某個(gè)線程處于“等待”狀態(tài)。本文介紹異步模式的Winsock編程。

[[380553]]

 Winsock套接字的工作模式有兩種,分別是阻塞模式(同步模式)和非阻塞模式(異步模式)。阻塞模式下的Winsock函數(shù)會(huì)將程序的某個(gè)線程(如果程序中只有一個(gè)主線程,那么會(huì)導(dǎo)致整個(gè)程序處于“等待”狀態(tài))處于“等待”狀態(tài)。非阻塞模式的Winsock函數(shù)不會(huì)發(fā)生需要等待的情況。在異步模式下,當(dāng)一個(gè)函數(shù)執(zhí)行后會(huì)立刻返回,即使是操作沒(méi)有完成也會(huì)返回;當(dāng)函數(shù)執(zhí)行完成時(shí),會(huì)以某種方式通知應(yīng)用程序。顯然,異步模式更適合于Windows下的開發(fā)。本文介紹異步模式的Winsock編程。

當(dāng)一個(gè)套接字通過(guò)socket()函數(shù)創(chuàng)建后,默認(rèn)工作在阻塞模式下。為了使得套接字工作在非阻塞模式狀態(tài)下,就需要對(duì)套接字進(jìn)行設(shè)置,將其改編為非阻塞模式。改變套接字工作模式的方法有多種,為了基于Windows應(yīng)用程序的消息驅(qū)動(dòng)機(jī)制,這里只介紹常用的改變套接字的函數(shù)。該函數(shù)是WSAAsyncSelect()函數(shù),其定義如下: 

  1. int WSAAsyncSelect(  
  2.  SOCKET s,  
  3.  HWND hWnd,  
  4.  unsigned int wMsg,
  5.  long lEvent  
  6. ); 

WSAAsyncSelect()函數(shù)會(huì)把套接字設(shè)置為非阻塞模式,該函數(shù)會(huì)綁定指定套接字到一個(gè)窗口。當(dāng)該套接字有網(wǎng)絡(luò)事件發(fā)生時(shí),會(huì)向綁定窗口發(fā)送相應(yīng)的消息。該函數(shù)的參數(shù)含義說(shuō)明如下。

S:指定要改變工作模式為非阻塞模式的套接字。

hWnd:指定當(dāng)發(fā)生網(wǎng)絡(luò)事件時(shí)接收消息的窗口。

wMsg:指定當(dāng)網(wǎng)絡(luò)事件發(fā)生時(shí)向窗口發(fā)送的消息。該消息是一個(gè)自定義消息,定義自定義消息的方法是在 WM_USER 的基礎(chǔ)上加一個(gè)數(shù)值,比如(WM_USER + 1)。

lEvent:指定應(yīng)用程序感興趣的通知碼。它可以被指定為多個(gè)通知碼的組合。常用的通知碼有 FD_READ(套接字收到對(duì)端發(fā)來(lái)的數(shù)據(jù)包)、FD_ACCEPT(監(jiān)聽(tīng)中的套接字有連接請(qǐng)求)、FD_CONNECT(套接字成功連接到對(duì)方)和 FD_CLOSE(套接字對(duì)應(yīng)的連接被關(guān)閉)。在指定通知碼時(shí)不需要全部將其指定。對(duì)于基于 TCP 協(xié)議的客戶端來(lái)說(shuō),F(xiàn)D_ACCEPT 是沒(méi)有意義的;對(duì)于基于 TCP 的服務(wù)端來(lái)說(shuō),F(xiàn)D_CONNECT 是沒(méi)有意義的;對(duì)于基于 UDP 協(xié)議的客戶端和服務(wù)器端來(lái)說(shuō),F(xiàn)D_ACCEPT、FD_CONNECT 和 FD_CLOSE 都是沒(méi)有意義的。

在了解如何將套接字設(shè)置為非阻塞模式以后,這里完成一個(gè)簡(jiǎn)單的遠(yuǎn)程控制工具。這里要編寫的遠(yuǎn)程控制工具是基于C/S模式的,即客戶端/服務(wù)器端模式的架構(gòu)。客戶端通過(guò)發(fā)送控制命令,操作服務(wù)器端接收到控制命令后響應(yīng)相應(yīng)的事件,完成特定的功能。

這個(gè)遠(yuǎn)程控制的服務(wù)器端只簡(jiǎn)單實(shí)現(xiàn)以下幾個(gè)功能。

  •  向客戶端發(fā)送幫助信息。
  •  將服務(wù)器信息發(fā)送給客戶端。
  •  交換鼠標(biāo)的左右鍵和恢復(fù)鼠標(biāo)的左右鍵。
  •  打開光驅(qū)和關(guān)閉光驅(qū)。

1. 遠(yuǎn)程控制軟件框架設(shè)計(jì)

遠(yuǎn)程控制分為控制端和被控制端,控制端通常為客戶端,而被控制端通常為服務(wù)器端。對(duì)于客戶端來(lái)說(shuō),它需要3種通知碼,即FD_CONNECT、FD_CLOSE和FD_READ。對(duì)于服務(wù)器端來(lái)說(shuō),它需要3種通知碼,即FD_ACCEPT、FD_CLOSE和FD_READ,如圖1所示。

圖1  服務(wù)器端和客戶端通信

這里解釋一下圖1,并對(duì)它的框架設(shè)計(jì)進(jìn)行補(bǔ)充。對(duì)于服務(wù)器端(Server端)來(lái)說(shuō),它需要處于監(jiān)聽(tīng)狀態(tài)等待客戶端(Client端)發(fā)起的連接(FD_ACCEPT),在連接后會(huì)等待接收客戶端發(fā)來(lái)的控制命令(FD_READ),當(dāng)客戶端斷開連接后就可以結(jié)束此次通信了(FD_CLOSE)。對(duì)于客戶端來(lái)說(shuō),它需要等待確認(rèn)連接是否成功(FD_CONNET);當(dāng)連接成功后就可以向服務(wù)器端發(fā)送控制命令,并等待接收命令響應(yīng)結(jié)果(FD_READ);當(dāng)服務(wù)器端被關(guān)閉后,通信則強(qiáng)制被結(jié)束了(FD_CLOSE)。因此,服務(wù)器端需要的通知碼有FD_ACCEPT、FD_READ和FD_CLOSE,客戶端需要的通知碼有FD_CONNECT、FD_READ和FD_CLOSE。

客戶端向服務(wù)器端發(fā)送的命令為“字符串”類型的數(shù)據(jù)。當(dāng)服務(wù)器接收到客戶端發(fā)來(lái)的命令后,需要判斷命令,然后執(zhí)行相應(yīng)的功能。

服務(wù)器向客戶端反饋的執(zhí)行結(jié)果可能為字符串,也可能為其他的數(shù)據(jù)結(jié)構(gòu)類型的內(nèi)容。由于反饋數(shù)據(jù)的格式無(wú)法確定,那么對(duì)于服務(wù)器向客戶端反饋的信息必須做特殊的標(biāo)記,通過(guò)標(biāo)記判斷發(fā)送的數(shù)據(jù)格式。而客戶端接收到服務(wù)器端發(fā)來(lái)的數(shù)據(jù)后,必須對(duì)格式進(jìn)行解析,以便正確讀取服務(wù)器端返回的命令反饋結(jié)果。服務(wù)器端的反饋數(shù)據(jù)協(xié)議格式如圖2所示。

圖2  服務(wù)器端反饋數(shù)據(jù)協(xié)議格式

從圖2可以看出,服務(wù)器對(duì)于客戶端的反饋數(shù)據(jù)協(xié)議格式有3部分內(nèi)容,第1部分bType用于區(qū)分是文本數(shù)據(jù)和特定數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù),第2部分bClass用于區(qū)分不同的特定數(shù)據(jù)結(jié)構(gòu),第3部分szValue是真正的數(shù)據(jù)部分。對(duì)于服務(wù)器反饋的數(shù)據(jù),如果是文本數(shù)據(jù),那么客戶端直接將szValue中的字符串顯示輸出;如果反饋的是特定的數(shù)據(jù)結(jié)構(gòu),則必須區(qū)分是何種數(shù)據(jù)結(jié)構(gòu),最后按照直接的數(shù)據(jù)結(jié)構(gòu)解析szValue中的數(shù)據(jù)。將該協(xié)議格式定義為數(shù)據(jù)結(jié)構(gòu)體,如下: 

  1. #define TEXTMSG 't' // 表示文本信息  
  2. #define BINARYMSG 'b' // 表示特定的數(shù)據(jù)結(jié)構(gòu)  
  3. typedef struct _DATA_MSG  
  4.  
  5.   BYTE bType; // 數(shù)據(jù)的類型  
  6.   BYTE bClass; // 數(shù)據(jù)類型的補(bǔ)充  
  7.   char szValue[0x200]; // 數(shù)據(jù)的信息  
  8. }DATA_MSG, *PDATA_MSG; 

2. 遠(yuǎn)程控制軟件代碼要點(diǎn)

前面介紹了WSAAsyncSelect()函數(shù)原型和參數(shù)的含義,下面具體介紹WSAAsyncSelect()函數(shù)的使用。WSAAsyncSelect()函數(shù)在使用時(shí)會(huì)將指定的套接字、窗口句柄、自定義消息和通知碼關(guān)聯(lián)在一起,使用如下: 

  1. // 初始化 Winsock 庫(kù)  
  2. WSADATA wsaData;  
  3. WSAStartup(MAKEWORD(2, 2), &wsaData);  
  4. // 創(chuàng)建套接字并將其設(shè)置為非阻塞模式  
  5. m_ListenSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);  
  6. WSAAsyncSelect(m_ListenSock, GetSafeHwnd(), UM_SERVER, FD_ACCEPT); 

在代碼的WSAAsyncSelect()函數(shù)中,第1個(gè)參數(shù)是新創(chuàng)建的用于監(jiān)聽(tīng)的套接字m_ListenSock,第2個(gè)參數(shù)使用MFC的成員函數(shù)GetSafeHwnd()來(lái)得到當(dāng)前窗體的句柄,第3個(gè)參數(shù)UM_SERVER是一個(gè)自定義的類型,最后一個(gè)參數(shù)FD_ACCEPT是該套接字要接收的通知碼。函數(shù)中的第3個(gè)參數(shù)是一個(gè)自定義的消息。在服務(wù)器端,該消息的定義如下: 

  1. #define UM_SERVER (WM_USER + 200) 

當(dāng)有客戶端與服務(wù)器端連接時(shí),系統(tǒng)會(huì)發(fā)送UM_SERVER消息到與監(jiān)聽(tīng)套接字關(guān)聯(lián)的句柄指定的窗口。當(dāng)窗口收到該消息后,需要對(duì)該消息進(jìn)行處理。該處理函數(shù)也需要手動(dòng)進(jìn)行添加,添加有3處地方。

第1處是在類定義中添加,代碼如下: 

  1. // 生成的消息映射函數(shù)  
  2. //{{AFX_MSG(CServerDlg)  
  3. virtual BOOL OnInitDialog();  
  4. afx_msg void OnSysCommand(UINT nID, LPARAM lParam);  
  5. afx_msg void OnPaint(); 
  6. afx_msg HCURSOR OnQueryDragIcon();  
  7. afx_msg VOID OnSock(WPARAM wParam, LPARAM lParam);  
  8. afx_msg void OnClose();  
  9. //}}AFX_MSG  
  10. DECLARE_MESSAGE_MAP() 

在這里添加afx_msg VOID OnSock(WPARAM wParam, LPARAM lParam);

第2處在類實(shí)現(xiàn)中添加對(duì)應(yīng)的函數(shù)實(shí)現(xiàn)代碼,如下: 

  1. VOID CServerDlg::OnSock(WPARAM wParam, LPARAM lParam)  
  2.  

第3處是要添加消息映射,代碼如下: 

  1. BEGIN_MESSAGE_MAP(CServerDlg, CDialog)  
  2. //{{AFX_MSG_MAP(CServerDlg)  
  3. ON_WM_SYSCOMMAND()  
  4. ON_WM_PAINT()  
  5. ON_WM_QUERYDRAGICON()  
  6. ON_MESSAGE(UM_SERVER, OnSock)  
  7. ON_WM_CLOSE()  
  8. //}}AFX_MSG_MAP  
  9. END_MESSAGE_MAP() 

在這里添加ON_MESSAGE(UM_SERVER, OnSock)。

通過(guò)以上3步,在程序中就可以接收并響應(yīng)對(duì)UM_SERVER消息的處理。

3. 遠(yuǎn)程控制界面布局

首先來(lái)看遠(yuǎn)程控制客戶端與服務(wù)器端的窗口界面,如圖3所示。

圖3  遠(yuǎn)程控制端與服務(wù)器端界面布局

在圖3中,SERVER表示服務(wù)器端,Client表示客戶端。服務(wù)器端(Server)運(yùn)行在虛擬機(jī)中,客戶端(Client)運(yùn)行在物理機(jī)中。通過(guò)圖3可以看出,物理機(jī)中客戶端與服務(wù)器端是可以正常進(jìn)行通信的。

服務(wù)器端的軟件只有一個(gè)用于顯示多行文本的編輯框。該界面比較簡(jiǎn)單。

客戶端軟件在IP地址后的編輯框中輸入服務(wù)器端的IP地址,然后單擊“連接”按鈕,客戶端會(huì)與遠(yuǎn)端的服務(wù)器進(jìn)行連接。當(dāng)連接成功后,輸入IP地址的編輯框會(huì)處于只讀狀態(tài),“連接”按鈕變?yōu)?ldquo;斷開連接”按鈕。對(duì)于發(fā)送命令后的編輯框變?yōu)榭捎脿顟B(tài),“發(fā)送”按鈕也變?yōu)榭捎脿顟B(tài)。

對(duì)于軟件界面的布局,大家可以自行調(diào)整。

4. 服務(wù)器端代碼的實(shí)現(xiàn)

當(dāng)服務(wù)器啟動(dòng)時(shí),需要?jiǎng)?chuàng)建套接字,并將套接字設(shè)置為異步模式,綁定IP地址和端口號(hào)并使其處于監(jiān)聽(tīng)狀態(tài),代碼如下: 

  1. BOOL CServerDlg::OnInitDialog()  
  2.  
  3.   ……  
  4.   // 添加其他初始化代碼  
  5.   // 初始化 Winsock 庫(kù)  
  6.   WSADATA wsaData;  
  7.   WSAStartup(MAKEWORD(2, 2), &wsaData);  
  8.   // 創(chuàng)建套接字并將其設(shè)置為非阻塞模式  
  9.   m_ListenSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 
  10.   WSAAsyncSelect(m_ListenSock, GetSafeHwnd(), UM_SERVER, FD_ACCEPT);  
  11.   sockaddr_in addr;  
  12.   addr.sin_family = AF_INET 
  13.   addr.sin_addr.S_un.S_addr = ADDR_ANY 
  14.   addr.sin_port = htons(5555);  
  15.   // 綁定 IP 地址及 5555 端口,并處于監(jiān)聽(tīng)狀態(tài)  
  16.   bind(m_ListenSock, (SOCKADDR*)&addr, sizeof(addr));  
  17.   listen(m_ListenSock, 1);  
  18.   return TRUE; // return TRUE unless you set the focus to a control  

當(dāng)客戶端與服務(wù)器端進(jìn)行連接時(shí),需要處理通知碼FD_ACCEPT,并且創(chuàng)建與客戶端進(jìn)行通信的新的套接字。對(duì)于新的套接字也需要設(shè)置為異步模式,并且需要設(shè)置FD_READ和FD_CLOSE兩個(gè)通知碼。代碼如下: 

  1. VOID CServerDlg::OnSock(WPARAM wParam, LPARAM lParam)  
  2.  
  3.   if ( WSAGETSELECTERROR(lParam) )  
  4.   {  
  5.     return ;  
  6.   }  
  7.   switch ( WSAGETSELECTEVENT(lParam))  
  8.   {  
  9.     // 處理 FD_ACCEPT  
  10.   case FD_ACCEPT:  
  11.     {  
  12.       sockaddr_in ClientAddr;  
  13.       int nSize = sizeof(ClientAddr);  
  14.       m_ClientSock = accept(m_ListenSock, (SOCKADDR*)&ClientAddr, &nSize);  
  15.       WSAAsyncSelect(m_ClientSock, GetSafeHwnd(), UM_SERVER, FD_READ | FD_CLOSE);  
  16.       m_StrMsg.Format("請(qǐng)求地址是%s:%d",  
  17.         inet_ntoa(ClientAddr.sin_addr), ntohs(ClientAddr.sin_port));  
  18.       DATA_MSG DataMsg;  
  19.       DataMsg.bType = TEXTMSG 
  20.       DataMsg.bClass = 0 
  21.       lstrcpy(DataMsg.szValue, HELPMSG);  
  22.       send(m_ClientSock, (const char *)&DataMsg, sizeof(DataMsg), 0);  
  23.       break;  
  24.     }  
  25.     // 處理 FD_READ  
  26.   case FD_READ:  
  27.     { 
  28.       char szBuf[MAXBYTE] = { 0 };  
  29.       recv(m_ClientSock, szBuf, MAXBYTE, 0);  
  30.       DispatchMsg(szBuf);  
  31.       m_StrMsg = "對(duì)方發(fā)來(lái)命令: " 
  32.       m_StrMsg += szBuf; 
  33.        break; 
  34.     }  
  35.     // 處理 FD_CLOSE  
  36.   case FD_CLOSE:  
  37.     {  
  38.       closesocket(m_ClientSock);  
  39.       m_StrMsg = "對(duì)方關(guān)閉連接" 
  40.       break;  
  41.     }  
  42.   }  
  43.   InsertMsg();  

在代碼中,當(dāng)響應(yīng)FD_READ通知碼時(shí)會(huì)接收客戶端發(fā)來(lái)的命令,并通過(guò)DispatchMsg()函數(shù)處理客戶端發(fā)來(lái)的命令。在OnSock()函數(shù)的最后有一個(gè)InsertMsg()函數(shù),該函數(shù)用于將接收的命令顯示到界面上對(duì)應(yīng)的消息編輯框中。

DispatchMsg()函數(shù)用于處理客戶端發(fā)來(lái)的命令,該代碼如下: 

  1. VOID CServerDlg::DispatchMsg(char *szBuf)  
  2.  
  3.   DATA_MSG DataMsg;  
  4.   ZeroMemory((void*)&DataMsg, sizeof(DataMsg));  
  5.   if ( !strcmp(szBuf, "help") )  
  6.   {  
  7.     DataMsg.bType = TEXTMSG 
  8.     DataMsg.bClass = 0 
  9.     lstrcpy(DataMsg.szValue, HELPMSG);  
  10.   }  
  11.   else if ( !strcmp(szBuf, "getsysinfo"))  
  12.   {  
  13.     SYS_INFO SysInfo;  
  14.     GetSysInfo(&SysInfo);  
  15.     DataMsg.bType = BINARYMSG 
  16.     DataMsg.bClass = SYSINFO 
  17.     memcpy((void *)DataMsg.szValue, (const char *)&SysInfo, sizeof(DataMsg));  
  18.   }  
  19.   else if ( !strcmp(szBuf, "open") )  
  20.   {  
  21.     SetCdaudio(TRUE);  
  22.     DataMsg.bType = TEXTMSG 
  23.     DataMsg.bClass = 0 
  24.     lstrcpy(DataMsg.szValue, "open 命令執(zhí)行完成");  
  25.   }  
  26.   else if ( !strcmp(szBuf, "close") )  
  27.   {  
  28.     SetCdaudio(FALSE);  
  29.     DataMsg.bType = TEXTMSG 
  30.     DataMsg.bClass = 0 
  31.     lstrcpy(DataMsg.szValue, "close 命令執(zhí)行完成");  
  32.   }  
  33.   else if ( !strcmp(szBuf, "swap") )  
  34.   {  
  35.     SetMouseButton(TRUE);  
  36.     DataMsg.bType = TEXTMSG 
  37.     DataMsg.bClass = 0 
  38.     lstrcpy(DataMsg.szValue, "swap 命令執(zhí)行完成");  
  39.   }  
  40.   else if ( !strcmp(szBuf, "restore") )  
  41.   {  
  42.     SetMouseButton(FALSE);  
  43.     DataMsg.bType = TEXTMSG 
  44.     DataMsg.bClass = 0 
  45.     lstrcpy(DataMsg.szValue, "restore 命令執(zhí)行完成");  
  46.   }  
  47.   else 
  48.   {  
  49.     DataMsg.bType = TEXTMSG 
  50.     DataMsg.bClass = 0 
  51.     lstrcpy(DataMsg.szValue, "無(wú)效的指令");  
  52.   }  
  53.   // 發(fā)送命令執(zhí)行情況給客戶端  
  54.   send(m_ClientSock, (const char *)&DataMsg, sizeof(DataMsg), 0);  

在DispatchMsg()函數(shù)中,通過(guò)if()…else if()…else()比較客戶端發(fā)來(lái)的命令執(zhí)行相應(yīng)的功能,并將執(zhí)行的結(jié)果發(fā)送給客戶端。

命令功能的實(shí)現(xiàn)函數(shù)如下: 

  1. VOID CServerDlg::GetSysInfo(PSYS_INFO SysInfo)  
  2.  
  3.   unsigned long nSize = 0 
  4.   SysInfo->OsVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);  
  5.   GetVersionEx(&SysInfo->OsVer);  
  6.   nSize = NAME_LEN 
  7.   GetComputerName(SysInfo->szComputerName, &nSize);  
  8.   nSize = NAME_LEN 
  9.   GetUserName(SysInfo->szUserName, &nSize);  
  10.  
  11. VOID CServerDlg::SetCdaudio(BOOL bOpen)  
  12.  
  13.   if ( bOpen )  
  14.   {  
  15.     // 打開光驅(qū)  
  16.     mciSendString("set cdaudio door open", NULL, NULL, NULL);  
  17.   }  
  18.   else  
  19.   {  
  20.     // 關(guān)閉光驅(qū)  
  21.     mciSendString("set cdaudio door closed", NULL, NULL, NULL);  
  22.   }  
  23.  
  24. VOID CServerDlg::SetMouseButton(BOOL bSwap)  
  25.  
  26.   if ( bSwap)  
  27.   {  
  28.     // 交換  
  29.     SwapMouseButton(TRUE);  
  30.   }  
  31.   else  
  32.   {  
  33.   // 恢復(fù)  
  34.   SwapMouseButton(FALSE);  
  35.   }  

這里面對(duì)于getsysinfo命令,需要定義一個(gè)結(jié)構(gòu)體,具體如下: 

  1. #define HELPMSG "幫助信息: \r\n" \  
  2.  "\t help : 顯示幫助菜單 \r\n" \  
  3.  "\t getsysinfo : 獲得對(duì)方主機(jī)信息\r\n" \ 
  4.  "\t open : 打開光驅(qū) \r\n" \  
  5.  "\t close : 關(guān)閉光驅(qū) \r\n" \  
  6.  "\t swap : 交換鼠標(biāo)左右鍵 \r\n" \  
  7.  "\t restore : 恢復(fù)鼠標(biāo)左右鍵" \  
  8. #define NAME_LEN 20  
  9. typedef struct _SYS_INFO  
  10.  
  11.   OSVERSIONINFO OsVer; // 保存操作系統(tǒng)信息  
  12.   char szComputerName[NAME_LEN]; // 保存計(jì)算機(jī)名  
  13.   char szUserName[NAME_LEN]; // 保存當(dāng)前登錄名  
  14. }SYS_INFO, *PSYS_INFO; 

該結(jié)構(gòu)體不是文本類型的數(shù)據(jù),需要在反饋協(xié)議中填充bClass字段。對(duì)于getsysinfo命令,該bClass字段填充的內(nèi)容為“SYSINFO”。SYSINFO的定義如下: 

  1. #define SYSINFO 0x01L 

調(diào)用mciSendString()函數(shù)需要添加頭文件和庫(kù)文件,具體如下: 

  1. #include <mmsystem.h>  
  2. #pragma comment (lib, "Winmm") 

至此,服務(wù)器端的主要功能就介紹完了,最后還有兩個(gè)函數(shù)沒(méi)有列出,分別是InsertMsg()函數(shù)和釋放Winsock庫(kù)的部分,代碼如下: 

  1. void CServerDlg::OnClose()  
  2.  
  3.   // 添加處理程序代碼或調(diào)用默認(rèn)方法  
  4.   // 關(guān)閉監(jiān)聽(tīng)套接字,并釋放 Winsock 庫(kù)  
  5.   closesocket(m_ClientSock);  
  6.   closesocket(m_ListenSock);  
  7.   WSACleanup();  
  8.   CDialog::OnClose();  
  9.  
  10. VOID CServerDlg::InsertMsg()  
  11.  
  12.   CString strMsg;  
  13.   GetDlgItemText(IDC_MSG, strMsg);  
  14.   m_StrMsg += "\r\n"; 
  15.   m_StrMsg += "----------------------------------------\r\n";  
  16.   m_StrMsg += strMsg;  
  17.   SetDlgItemText(IDC_MSG, m_StrMsg);  
  18.   m_StrMsg = "" 

5. 客戶端代碼的實(shí)現(xiàn)

客戶端的代碼基本與服務(wù)端的代碼類似,這里就不再說(shuō)明。

連接遠(yuǎn)程服務(wù)器的代碼如下: 

  1. void CClientDlg::OnBtnConnect()  
  2.  
  3.   // 添加處理程序代碼  
  4.   char szBtnName[10] = { 0 };  
  5.   GetDlgItemText(IDC_BTN_CONNECT, szBtnName, 10);  
  6.   // 斷開連接  
  7.   if ( !lstrcmp(szBtnName, "斷開連接") )  
  8.   {  
  9.     SetDlgItemText(IDC_BTN_CONNECT, "連接");  
  10.     (GetDlgItem(IDC_SZCMD))->EnableWindow(FALSE);  
  11.     (GetDlgItem(IDC_BTN_SEND))->EnableWindow(FALSE);  
  12.     (GetDlgItem(IDC_IPADDR))->EnableWindow(TRUE);  
  13.     closesocket(m_Socket);  
  14.     m_StrMsg = "主動(dòng)斷開連接" 
  15.     InsertMsg();  
  16.     return ;  
  17.   }  
  18.   // 連接遠(yuǎn)程服務(wù)器端  
  19.   char szIpAddr[MAXBYTE] = { 0 };  
  20.   GetDlgItemText(IDC_IPADDR, szIpAddr, MAXBYTE);  
  21.   m_Socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);  
  22.   WSAAsyncSelect(m_Socket,GetSafeHwnd(),UM_CLIENT, FD_READ | FD_CONNECT | FD_CLOSE);  
  23.   sockaddr_in ServerAddr;  
  24.   ServerAddr.sin_family = AF_INET 
  25.   ServerAddr.sin_addr.S_un.S_addr = inet_addr(szIpAddr);  
  26.   ServerAddr.sin_port = htons(5555);  
  27.   connect(m_Socket, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr));  
  28. }  

響應(yīng)通知碼的函數(shù)如下: 

  1. VOID CClientDlg::OnSock(WPARAM wParam, LPARAM lParam)  
  2.  
  3.   if ( WSAGETSELECTERROR(lParam) )  
  4.   {  
  5.     return ;  
  6.   }  
  7.   switch ( WSAGETSELECTEVENT(lParam)) 
  8.   {  
  9.     // 處理 FD_ACCEPT  
  10.   case FD_CONNECT:  
  11.     {  
  12.       (GetDlgItem(IDC_SZCMD))->EnableWindow(TRUE);  
  13.       (GetDlgItem(IDC_BTN_SEND))->EnableWindow(TRUE);  
  14.       (GetDlgItem(IDC_IPADDR))->EnableWindow(FALSE);  
  15.       SetDlgItemText(IDC_BTN_CONNECT, "斷開連接");  
  16.       m_StrMsg = "連接成功" 
  17.       break;  
  18.     }  
  19.     // 處理 FD_READ  
  20.   case FD_READ:  
  21.     {  
  22.       DATA_MSG DataMsg;  
  23.       recv(m_Socket, (char *)&DataMsg, sizeof(DataMsg), 0);  
  24.       DispatchMsg((char *)&DataMsg);  
  25.       break;  
  26.     }  
  27.     // 處理 FD_CLOSE  
  28.   case FD_CLOSE:  
  29.     {  
  30.       (GetDlgItem(IDC_SZCMD))->EnableWindow(FALSE);  
  31.       (GetDlgItem(IDC_BTN_SEND))->EnableWindow(FALSE);  
  32.       (GetDlgItem(IDC_IPADDR))->EnableWindow(TRUE);  
  33.       closesocket(m_Socket);  
  34.       m_StrMsg = "對(duì)方關(guān)閉連接" 
  35.       break;  
  36.     }  
  37.   }  
  38.   InsertMsg();  
  39. }  

發(fā)送命令到遠(yuǎn)程服務(wù)器端的代碼如下: 

  1. void CClientDlg::OnBtnSend()  
  2.  
  3.   // 添加處理程序代碼  
  4.   char szBuf[MAXBYTE] = { 0 };  
  5.   GetDlgItemText(IDC_SZCMD, szBuf, MAXBYTE);  
  6.   send(m_Socket, szBuf, MAXBYTE, 0);  
  7. }  

處理服務(wù)器端反饋結(jié)果的代碼如下: 

  1. VOID CClientDlg::DispatchMsg(char *szBuf)  
  2.  
  3.   DATA_MSG DataMsg;  
  4.   memcpy((void*)&DataMsg, (const void *)szBuf, sizeof(DATA_MSG));  
  5.   if ( DataMsg.bType == TEXTMSG ) 
  6.   {  
  7.     m_StrMsg = DataMsg.szValue;  
  8.   }  
  9.   else  
  10.   {  
  11.     if ( DataMsg.bClass == SYSTEMINFO )  
  12.     {  
  13.       ParseSysInfo((PSYS_INFO)&DataMsg.szValue);  
  14.     }  
  15.   }  
  16. }  

解析服務(wù)器端信息的代碼如下: 

  1. VOID CClientDlg::ParseSysInfo(PSYS_INFO SysInfo)  
  2.  
  3.   if ( SysInfo->OsVer.dwPlatformId == VER_PLATFORM_WIN32_NT )  
  4.   {  
  5.     if ( SysInfo->OsVer.dwMajorVersion == 5 && SysInfo->OsVer.dwMinorVersion == 1 )  
  6.     {  
  7.       m_StrMsg.Format("對(duì)方系統(tǒng)信息:\r\n\t Windows XP %s", SysInfo->OsVer. szCSDVersion);  
  8.     } 
  9.      else if ( SysInfo->OsVer.dwMajorVersion == 5 && SysInfo->OsVer.dwMinorVersion== 0)  
  10.     {  
  11.       m_StrMsg.Format("對(duì)方系統(tǒng)信息:\r\n\t Windows 2K");  
  12.     }  
  13.   }  
  14.   else  
  15.   { 
  16.      m_StrMsg.Format("對(duì)方系統(tǒng)信息:\r\n\t Other System \r\n");  
  17.   }  
  18.   m_StrMsg += "\r\n";  
  19.   m_StrMsg += "\t Computer Name is ";  
  20.   m_StrMsg += SysInfo->szComputerName;  
  21.   m_StrMsg += "\r\n";  
  22.   m_StrMsg += "\t User Name is";  
  23.   m_StrMsg += SysInfo->szUserName;  
  24. }  

到這里,遠(yuǎn)程控制的代碼就完成了。如果要實(shí)現(xiàn)更多的功能,可能該框架無(wú)法進(jìn)行更好的擴(kuò)充。該實(shí)例主要為了演示非阻塞模式的Winsock應(yīng)用的開發(fā)。如果該實(shí)例中的套接字使用阻塞模式的話,那么就必須配合多線程來(lái)完成,將接收的部分單獨(dú)放在一個(gè)線程中,否則接收數(shù)據(jù)的函數(shù)recv()在等待接收數(shù)據(jù)的到來(lái)時(shí)會(huì)將整個(gè)程序“卡死”。 

 

責(zé)任編輯:龐桂玉 來(lái)源: 計(jì)算機(jī)與網(wǎng)絡(luò)安全
相關(guān)推薦

2021-03-03 12:20:42

網(wǎng)絡(luò)安全DLL編程

2020-05-08 10:34:30

Spring非阻塞編程

2021-06-11 13:40:17

網(wǎng)絡(luò)安全專殺工具病毒

2021-03-05 13:46:56

網(wǎng)絡(luò)安全遠(yuǎn)程線程

2021-01-26 13:45:03

網(wǎng)絡(luò)安全Winsock編程

2021-02-23 10:20:07

網(wǎng)絡(luò)安全進(jìn)程代碼

2021-02-21 18:19:43

網(wǎng)絡(luò)安全網(wǎng)絡(luò)安全編程創(chuàng)建進(jìn)程

2023-09-06 14:05:14

2016-10-10 00:18:27

2021-06-18 09:55:09

網(wǎng)絡(luò)安全目錄監(jiān)控

2011-03-17 13:32:45

2021-05-12 14:57:13

網(wǎng)絡(luò)安全密碼代碼

2021-06-24 08:37:34

網(wǎng)絡(luò)安全內(nèi)核代碼

2021-06-15 11:16:24

網(wǎng)絡(luò)安全U盤軟件

2021-04-19 10:26:41

網(wǎng)絡(luò)安全PE文件

2021-05-24 11:55:55

網(wǎng)絡(luò)安全Windows鉤子函數(shù)

2021-03-01 11:20:13

網(wǎng)絡(luò)安全多線程代碼

2021-01-18 10:35:18

網(wǎng)絡(luò)安全Windows代碼

2012-05-21 10:15:48

2012-05-17 16:20:24

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

国产精品va在线| 91精品国产麻豆| 日韩av电影免费在线| 亚洲一区精品在线观看| 欧美日韩视频| 亚洲精选在线观看| 天天综合成人网| 蜜桃视频在线观看播放| 国产精品久久久久三级| 国产视频一区二区不卡| 在线观看亚洲一区二区| 亚洲日本黄色| 精品国产一区久久久| 免费的av网站| 欧美久久一区二区三区| 91成人国产精品| 国产精品久久久久9999爆乳| 亚洲精品传媒| 91在线观看高清| 91久久中文字幕| 日韩欧美国产另类| 亚洲看片一区| 欧美激情亚洲综合一区| 中文字幕91视频| 在线亚洲a色| 精品国产乱码久久久久久免费| 国产 porn| 三妻四妾的电影电视剧在线观看| 亚洲少妇最新在线视频| 视频一区二区精品| 日韩一二三四| av一区二区三区四区| 亚洲free性xxxx护士hd| 影音先锋国产在线| 久久精品中文| 热久久99这里有精品| 国产污片在线观看| 欧美日韩免费观看一区=区三区| 亚洲天堂av女优| 一级性生活大片| 老司机凹凸av亚洲导航| 欧美电影免费观看完整版| 污色网站在线观看| 视频一区在线免费看| 懂色aⅴ精品一区二区三区蜜月| 丰满人妻一区二区三区53号| 国产剧情在线| 一区二区三区四区在线免费观看 | 亚洲欧美另类综合| 国产一区二区剧情av在线| 国产精品偷伦视频免费观看国产| 无码人妻一区二区三区线| 美女诱惑一区| 国产精品久久久久久av福利软件| 亚洲精品中文字幕乱码三区91| 亚洲理伦在线| 奇米一区二区三区四区久久| 波多野结衣 久久| 老妇喷水一区二区三区| 国产精品h在线观看| 亚洲国产成人精品女人久久| 三级精品在线观看| 国产精品免费一区| 91久久精品国产91性色69| 九色综合狠狠综合久久| 成人黄色av播放免费| 国产精品无码久久av| 国产乱码精品1区2区3区| 999视频在线观看| 可以免费观看的毛片| 不卡视频一二三四| 欧美激情第一页在线观看| 国产高清一级毛片在线不卡| 国产精品色一区二区三区| 在线视频福利一区| 日本动漫同人动漫在线观看| 午夜精品福利久久久| 成人三级视频在线播放| 亚洲精品777| 欧美成人精品3d动漫h| 制服丝袜第一页在线观看| 欧美极品在线观看| 色婷婷综合久久久久| 五月婷婷一区二区| 亚洲综合欧美| 成人福利免费观看| 亚洲国产精品无码久久| 国产亚洲综合av| 在线观看av的网址| 性国裸体高清亚洲| 欧美一三区三区四区免费在线看 | 亚洲av无码一区二区乱子伦| 99r国产精品| 亚洲欧美久久234| 美女精品视频| 欧美三级电影在线看| 亚洲欧美日韩中文字幕在线观看| 欧美日韩一区二区三区四区不卡| 中文字幕日韩欧美| 男人天堂中文字幕| 久久99精品久久久久久动态图 | 国产欧美久久一区二区三区| 久久视频在线视频| 日本中文字幕在线| 国产电影一区二区三区| 欧美一区二区三区四区五区六区| av网址在线看| 在线免费一区三区| 男人网站在线观看| 99精品视频在线观看播放| 97色在线播放视频| 国产ts人妖调教重口男| 国产三级三级三级精品8ⅰ区| japanese在线播放| 日韩五码电影| 亚洲色图在线观看| 国产午夜久久久| 激情国产一区二区| 丝袜足脚交91精品| 综合日韩av| 精品久久久网站| 国产性生活大片| 日本不卡中文字幕| 欧美二区三区| 国产传媒av在线| 日韩免费高清视频| 欧美风情第一页| 蜜臀av性久久久久蜜臀aⅴ四虎| 国产在线一区二区三区欧美| 丝袜美腿av在线| 91麻豆精品国产91| 精品女人久久久| 日韩国产欧美一区二区三区| 精品日本一区二区三区在线观看| 羞羞的视频在线观看| 欧美一区欧美二区| 小泽玛利亚一区| 精品亚洲国内自在自线福利| 涩涩日韩在线| 主播大秀视频在线观看一区二区| 亚洲乱码av中文一区二区| 黄色片视频网站| 96av麻豆蜜桃一区二区| 日韩人妻无码精品久久久不卡| 国产精品视频首页| 久久久国产精品视频| 中文字幕一二区| 国产精品伦一区| 一起操在线视频| 久久精品国产亚洲夜色av网站 | 中文字幕高清一区| wwwwxxxx日韩| 欧美偷拍自拍| 国产在线精品成人一区二区三区| 日韩免费网站| 欧美群妇大交群的观看方式| 亚洲人做受高潮| 国产真实乱偷精品视频免| 少妇熟女一区二区| 亚洲一区电影| 国模精品视频一区二区三区| 五月婷中文字幕| 色悠悠久久综合| 国产黄色录像视频| 精品一区中文字幕| 日本a级片在线播放| 精品亚洲自拍| 国产成人精品综合| 美女免费久久| 亚洲精品一线二线三线无人区| 国产乡下妇女做爰毛片| 91免费观看国产| 国产精品区在线| 欧美日韩少妇| 欧洲av一区| av日韩在线免费观看| 欧美黄色小视频| 男人天堂网在线| 欧美日韩国产精品自在自线| 欧美激情精品久久| 久久久无码精品亚洲日韩按摩| 天美星空大象mv在线观看视频| 91精品一区二区三区综合| 国产精品v欧美精品v日韩精品| 一级毛片久久久| 久久久精品国产亚洲| 污视频在线免费观看| 欧美在线视频全部完| 国产一区二区视频在线观看免费| 99国产精品久久久久久久久久久| 色片在线免费观看| 亚洲免费成人| 91九色国产ts另类人妖| 天堂资源在线亚洲| 成人亚洲综合色就1024| 韩漫成人漫画| 九九视频这里只有精品| 国产玉足榨精视频在线观看| 欧美一区二区三区在线视频| 男人天堂2024| 亚洲国产乱码最新视频| 性爱在线免费视频| 97se亚洲国产综合自在线观| 人妻少妇偷人精品久久久任期| 亚洲欧美日韩国产一区二区| 国产在线无码精品| 日本不卡免费一区| 欧美凹凸一区二区三区视频| 视频在线观看免费影院欧美meiju| 国产999精品久久久| 波多野结衣在线高清| 色妞一区二区三区| 极品美乳网红视频免费在线观看| 精品精品国产高清一毛片一天堂| 夜夜躁狠狠躁日日躁av| 日韩欧美在线中文字幕| 精品少妇久久久久久888优播| 国产精品久久久久久久浪潮网站 | 26uuu久久噜噜噜噜| 日本成人不卡| 久久中国妇女中文字幕| a中文在线播放| 亚洲欧美视频在线| 在线观看xxx| 欧美精品一区二区三区蜜桃视频| 国产婷婷在线视频| 欧美日韩国产区一| 中文字幕第2页| 日本韩国欧美一区| 日韩综合在线观看| 欧美日韩一区二区三区在线免费观看| 久久久久亚洲av无码专区| 亚洲日穴在线视频| 小嫩苞一区二区三区| 国产精品日韩精品欧美在线| 91精品久久久久久久久久久久| 久久五月婷婷丁香社区| av网页在线观看| 99久久精品国产精品久久| 国产精品果冻传媒| 成人午夜视频免费看| 性感美女一区二区三区| 成人综合在线视频| 国产香蕉精品视频| 99视频一区二区三区| 强迫凌虐淫辱の牝奴在线观看| 不卡的看片网站| 精品黑人一区二区三区观看时间| 91网站在线播放| 深爱五月激情网| 久久嫩草精品久久久精品一| 国产肥白大熟妇bbbb视频| 国产午夜一区二区三区| 国产成人在线网址| 亚洲天堂av老司机| 国产一级淫片免费| 精品二区三区线观看| 久久国产黄色片| 欧美午夜影院一区| 国产精品爽爽久久| 精品少妇一区二区三区免费观看| 国产77777| 亚洲精品一区二区久| yw视频在线观看| 久久久精品在线| 岛国大片在线免费观看| 日本在线视频免费| 成人观看网址| 精品国产露脸精彩对白| 欧日韩在线视频| 成人免费观看av| 国产精品少妇在线视频| 日本中文字幕不卡| xxx国产在线观看| 国产超碰在线一区| 国精产品一区一区三区免费视频| 欧美激情在线一区二区三区| 亚洲精品无人区| 欧美影院在线| 精品欧美一区二区久久久伦| 欧美色图激情小说| 一级特黄妇女高潮| 99在线热播精品免费99热| 五月婷婷深爱五月| 国产成人aaaa| 亚洲精品午夜视频| 亚洲精品日韩专区silk | 性做久久久久久久久| 中文字幕第四页| 91精品免费在线观看| 香蕉久久一区二区三区| 中文字幕日韩欧美精品在线观看| 牛牛电影国产一区二区| 国产国语刺激对白av不卡| 精品入口麻豆88视频| 免费看国产精品一二区视频| 久久久久久久久久久久久久| 日韩人妻精品无码一区二区三区| 久久福利视频一区二区| 精品人妻一区二区免费视频| 中文字幕亚洲不卡| 国语对白永久免费| 欧美va亚洲va| av在线播放网| 97在线精品国自产拍中文| 国产电影一区| 清纯唯美一区二区三区| 在线观看一区视频| 亚洲欧美天堂在线| 久久久久久影视| 国产福利拍拍拍| 欧美一区二区三区日韩视频| 国产黄在线看| 18久久久久久| 成人精品毛片| 在线日韩av永久免费观看| 日日摸夜夜添夜夜添亚洲女人| 中文字幕人妻一区| 亚洲蜜臀av乱码久久精品| 国产女主播喷水视频在线观看| 精品处破学生在线二十三| 免费a在线看| 国产精品久久视频| 欧美猛男男男激情videos| 成年人午夜免费视频| 国产精品1024久久| 成人在线观看高清| 欧美福利视频导航| 亚洲成人三级| 国产日韩欧美成人| 久久神马影院| 超碰在线公开97| 国产精品每日更新在线播放网址| 日本中文字幕久久| 亚洲欧美精品在线| 在线免费三级电影网站| 久久99精品国产99久久| 在线免费观看欧美| 一区二区免费在线观看视频| 午夜亚洲国产au精品一区二区| 亚洲精品久久久狠狠狠爱| 欧美黄色片免费观看| 成午夜精品一区二区三区软件| 国产激情片在线观看| 国产999精品久久| 国产一级二级三级| 亚洲第一网站免费视频| 性欧美1819sex性高清大胸| 亚洲aⅴ男人的天堂在线观看| 亚洲精品91| 一卡二卡三卡四卡五卡| 玉米视频成人免费看| 亚洲乱码在线观看| 久久久久久久爱| 蜜桃久久久久| 国产日韩一区二区在线观看| 国产午夜精品一区二区| 正在播放木下凛凛xv99| 精品国产一区av| 久久视频社区| 久久国产午夜精品理论片最新版本| 成人激情免费电影网址| 久久免费激情视频| 国产亚洲欧美日韩一区二区| 九七影院97影院理论片久久| 99精品一区二区三区的区别| 国产一区在线视频| 亚洲一区欧美在线| 一本色道久久综合狠狠躁篇怎么玩| 欧美极品在线| 国产精品igao激情视频| 99久久久精品免费观看国产蜜| 在线视频一区二区三区四区| jizz亚洲女人高潮大叫| 日本午夜精品一区二区三区| 蜜臀av亚洲一区中文字幕| www欧美com| 亚洲国产精品小视频| 亚洲天堂1区| 男人添女人下部视频免费| 久久婷婷一区二区三区| 在线免费看毛片| 久久久久久中文| 国产欧美日韩影院| 免费网站在线观看黄| 精品久久久久久久久久久久| 1024视频在线| 国产精品久久一区二区三区| 肉丝袜脚交视频一区二区| 五月天丁香激情| 亚洲精品综合精品自拍| 欧美欧美在线| 国产免费999| 亚洲福利视频一区| 日本视频不卡| 久久免费视频1| 国产成人精品综合在线观看| 日本特级黄色片| 欧美日本中文字幕| 欧美日韩有码|