亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 16.5.2 網絡聊天室程序的實現.txt

?? 網上第一本以TXT格式的VC++深入詳解孫鑫的書.全文全以TXT格式,并每一章節都分了目錄,清晰易讀
?? TXT
?? 第 1 頁 / 共 2 頁
字號:
16.5.2  網絡聊天室程序的實現
下面采用基于消息的異步套接字實現前面第 15章中已經實現的網絡聊天程序。首先,新建一個基于
對話框的工程,工程名取為: Chat,并將該對話框資源上自動創建的控件全部刪除,然后添加一些
控件,本章實現的程序界面與第 15章 Chat程序的界面完全相同,所以可以直接復制后者己有的對
話框資源,具體的復制方法,本書前面章節中已經介紹過,這里不再贅述。 
1.加載套接字庫與前面使用套接字編程一樣,首先需要加載套接字庫并進行版本協商。上一章我們
使用了 MFC函數: MxSocket1nit來完成這一任務,但是該函數只能加載1. 1版本的套接字庫,本程
序中需要使用套接字庫 2.0版本中的一些函數,因此應該調用 WSAStartup函數初始化
程序所使用的套接字庫。同樣,應該在應用程序類,即在 CChatApp類的InitInstance函數中加載套
接字,因此,在該函數的開始位置添加下述如例 16-6所示的代碼。
例 16-6 

WORD wVersionRequested; 
WSADATA wsaData; 
int err; 
wVersionRequested = MAKEWORD( 2 , 2 ); 
err = WSAStartup( wVersionRequested, &wsaData ); 
i f ( err ! = 0 ) { 
return FALSE; 
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { 
WSACleanup( ); 
return FALSE; 

如果調用成功, WSAStartup函數將返回 0值;否則,它返回一個預定義的錯誤代碼。因此,在上述
如例 16-6所示代碼中,對此函數的返回值進行檢測,如果不是 O值,說明 WSAStartup函數調用失
敗, Initlnstance函數立即返回 FALSE值。
本例加載 2.2版本的 Winsock庫,如果版本不合要求,就調用 WSACleanup函數終止對套接字庫的使
用,然后 Ini tIn stance函數立即返回 FALSE值。
同樣,因為調用了 Winsock 2.0版本中的函數,所以還需要包含相應的頭文件: winsock2 .h。與上
一章的 Chat程序一樣,將該文件的包含語句放在 stdafx.h文件中,即在該文件中添加下面這條語
句: 
#include <winsock2.h> 
當然,還需要為 Chat工程鏈接 ws2_32.lib文件。 
2.創建并初始化套接字
接下來創建并初始化套接字,實現步驟與上一章的 Chat程序一樣,為 CChatD lg類增加一個 SOCKET
類型的成員變量: m_socket,即套接字描述符,并將其訪問權限設置為私有的。然后為 CChatDlg
類添加一個 BOOL類型的成員函數: InitSocket,用來初始化該類的套接字成員變量,該函數的實現
代碼如例 16-7所示。
例 16-7 

BOOL CChatDlg : : InitSocket() 
m_socket=WSASocket(AF_INET, SOCK_DGRAM , 0,NULL , 0, 0) ; 
if(INVALID_SOCKET==m_socket) 

MessageBox ( "創建套接字失敗!"); 
return FALSE; 

SOCKADDR_IN addrSock; 
addrSock . sin_addr.S_un.S_addr=htonl(INADDR_ANY) ; 
addrSock.sin_family=AF_INET; 
addrSock .sin-port=htons(6000); 
if(SOCKET_ERROR==bind(m_socket , (SOCKADDR*)&addrSock , sizeof(SOCKADDR 

) ) ) 
MessageBox("綁定失敗!"); 
return FALSE; 
}
 if(SOCKET_ERROR==WSAAsyncSelect(m_socket ,m_hWnd ,UM_SOCK,FD_READ)) 
MessageBox ( "注冊網絡讀取事件失敗!"); 
return FALSE; 
return TRUE; 

上一章示例中使用的是 socket函數創建套接字,這里使用 Winsock庫中的擴展函數 z WSASocket
來完成這一功能。
注意:在 Windows Sockets中,對增加的擴展函數來說,櫚樹 WSA前
綴。
在上述如例 16-7所示代碼中,接著對 WSASocket函數的返回值進行判斷,如果是 INVALID _ SOCKET,
則說明該函數調用失敗,于是提示用戶:"創建套接宇失敗!",井讓 InitSocket函數立即返回,返回
值是 FALSE。
如果套接字創建成功,接下來,就要將該套接宇綁定到某個 IP地址和端口上, WinSock 
2.0版本的庫中沒有提供 bind函數的擴展函數,所以這里仍使用該函數來完成套接字的綁定。首先
定義一個地址結構體 (SOCKADDR_IN)變量 : addrSock,并為其成員賦值。最后調用 bind函數,并
對其返回值進行判斷,如果是 SOCKET_ERROR,說明 bind函數調用出錯了,就提示用戶:"綁定失敗!"。
接下來,就可以調用 WSAAsyncSelect函數請求一個基于 Windows消息的網絡事件通知,該函數的第
一個參數就是標識請求網絡事件通知的套接字描述符:本例讓對話框窗口 
! 	接收消息,因此第二個參數就是該對話框的窗口句柄,即 CChatDlg類的 m hWnd成員:第三個參
數指定了一個自定義的消息 (UM_SOCK),一旦指定的網絡事件發生時,操作系統就會發送該自定義
的消息通知調用線程:第四個參數是注冊的事件,本例注冊了一個讀取事件 (FD_READ)。這樣,一旦
有數據到來,就會觸發 FD阻AD事件,系統就會通過 UM SOCK這則消息來通知調用線程,于是,在該
消息的響應函數中接收數據,就可以接收到數據了。上述代碼中,對 WSAAsyncSelect函數的返回值
作以判斷,如果函數調用失敗,則提示用戶:"注冊網絡讀取事件失敗!",并返回 FALSE。
如果上述操作全部成功,則 InitSocket函數返回 TRUE。這就是在InitSocket函數中對套接字進行
初始化的處理過程。然后可以在 CChatDlg類的 OnlnitDialog函數中調用這個函數,以便使程序完
成套接字的初始化工作。因此,在 OnlnitDialog函數最后的 return語句之前添加下面這條語句:
InitSocket() ; 
然后在 CChatDlg類的頭文件中,定義自定義消息: UM_SOCK,定義代碼如下所示: 
#define UM_SOCK 	WM_USER+1 
3.實現接收端功能
這里應注意,在注冊的事件發生后,操作系統向調用進程發送相應的消息時,還會將該事件相應的
信息一起傳遞給調用進程,這些信息是通過消息的兩個參數傳遞的。因此在定義 UM_SOCK消息響應
函數時應帶有 wParam和 lParamp這兩個參數。在 CChatDlg類的頭文件中添加如例 16-8所示代碼中
加灰顯示的那條代碼,即 UM SOCK消息響應函數 
原型的聲明。
例IJ 16-8 
// Generated message map functions 11{{AFX_MSG(CChatDlg) 
virtual BOOL OnlnitD工 alog ( ) ; 
afx_msg void OnSysCommand(UINT nID, LPARAM lParam) ; 
afx_msg void OnPaint(); 
afx_msg HCURSOR OnQueryDraglcon(); 

II}}AFX_ MSG 
afx_msg void OnSock(WPARAM, LPARAM); DECLARE_MESSAGE_MAP() 
接下來在 CChatD lg類的源文件中添加 UM SOCK 消息映射,即添加如例 16-9所示代碼中加灰顯示
的那條代碼。
例 16-9 

BEGIN_MESSAGE_MAP(CChatD1g , CDia1og) 
11{{AFX_MSG_MAP(CChatDlg) 
ON_WM_SYSCOMMAND() 
ON_WM_PAINT () 
ON_WM_QUERYDRAG工 CON( ) 
I /} } AFX_MSG_MAP 
ON_MESSAGE(UM_SOCK, OnSock) 

END_MESSAGE_MAP() 
最后就是該消息響應函數的實現,具體代碼如例 16-10所示。例 16-10 
void CChatDlg : : OnSock(WPARAM wParam, LPARAM lParam) 
{ 
1 . switch(LOWORD(lParam)) 
2. { 
3 . case FD READ : 
4. WSABUF wsabuf ; 
5 . wsabuf . buf=new char[2001; 

6 . wsabuf . len=200; 


7. DWORD dwRead; 

8. DWORD dwFlag=0; 

9. SOCKADDR_IN addrFrom; 

10. int len=sizeof(SOCKADDR) ; 

11. CString str; 

12. CString strTemp ; 


if(SOCKET_ERROR==WSARecvFrom(m_socket, &wsabuf,1, &dwRead, 
&dwFlag , 
13. (SOCKADDR*)&addrFrom, &len,NULL ,NULL)) 
14. 
15. MessageBox ( "接收數據失敗!"); 
. 
第16
16. delete[] wsabuf.buf; 
17. return; 

18. } 


19. str.Format("%s說:%s",inet_ntoa(addrFrom.sin_addr),wsabuf.buf); 
20. str+="\r\n"; 

21. GetDlgItemText(IDC_EDIT_RECV,strTemp); 

22. str+=strTemp; 


23. SetDlgItemText(IDC_EDIT_RECV,str); 
24. delete[] wsabuf.buf; 

25. break; 

26. } 



讀者可能會認為,既然我們只請求了一個基于Windows消息的網絡事件通知,即只請求了 FD_阻AD
這種網絡事件,那么在OnSock函數就可以直接調用WSARecvFrom函數接收數據了。這種想法本身并沒
有錯誤。但是需要注意,在基于套接字上請求網絡事件通知時,可以同時請求多個網絡事件,也就
是說,不但可以請求而'_READ網絡讀取事件,還可以同時請求 FD_WRITE網絡寫入事件,那么在對指
定的消息進行處理時,即在相應的消息響應函數中,就可以根據當前發生的網絡事件進行相應的處
理。在本例中,因為只請求了m-阻AD網絡讀取事件,所以在在OnSock函數可以直接調用WSARecvFrom
函數去接收數據。但這并不是一種良好的代碼設計風格。作為一種良好的代碼風格,應該在 此函數
中判斷是否是網絡讀取事件發生了,如果是,然后再讀取數據。
一旦網絡事件發生時,系統會發送自定義的消息通知調用線程,隨該消息發送的信息都是隨著捎息
的兩個參數發送的。當一個指定的網絡事件在指定的套接宇上發生時,應用程序窗口接收到指定的
消息,該消息的 wParam參數標識已經發生網絡事件的套接字, lParam參數的低位字標識己經發生
的網絡事件,高位字包含了任何錯誤代碼,也就是說通過取出lParam參數的低位字,就可以知道當
前發生的網絡事件類型。
因此在上述例16-10所示代碼的OnSock函數中,首先使用switch語句,利用LOWORD宏取出lParam參數
的低位字,井判斷是否是網絡讀取事件發生了,如果是,就調用Winsock庫的擴展函數WSARecvFrom
接收數據。在調用該函數之前,先根據其需要的參數定義一些變量。首先定義了一個WSABubf結構體
類型的變量: wsabuf,并為其成員賦值,將其緩沖區設置為2001個字節:接著,定義一個dwRead變量,
用來保存實際接收到的數據長度:又定義一個 SOCKADDR_IN結構體變量: addrFrom.用來接收發送方
的地址信息,接著定義了一個變量len,并用SOCKADDR IN地址結構體長度對其初始化。然后,就調
用WSWRecvFrom函數接收數據,第一個參數是套接宇描述符:第二個參數指定接收數據的WSABUF結構
體數組:第三個參數指定用來接收數據的WSABUF結構體變量的數目:第四個參數保存實際接收到的數
據:第五個參數是標志位,本例指定為o即可:第六個參數是用來接收發送方地址信息的地址結構體指
針;第七個參數是上一參數的長度:本例將最后兩個參數都設置為NULL。另外,因為數據接收操作是
在網絡讀取事件發生時進行的,所以一般這種讀取操作都能成功,但是為了代碼風格統一,在程序
中也可以對 WSARecvFrom函數的返回值進行判斷,如果出錯,利用MessageBox函數顯示一個消息框,
提示用戶:"接收數據失敗!",然后釋放己分配的內容,最后直接返回。
上述例 16-10所示代碼中的 OnSock函數在接收到數據后,將該數據進行格式化。首先,取出發送端
地址(保存在 addrFrom變量的 sin addr成員中),并將它轉換為點分十進制表示的字符串:接著,從
對話框的接收編輯框中取出己有的數據,保存到 strTemp變量中:接下來,將當前接收到的數據加上
回車換行符后,再加上 strTemp變量中保存的以前接收到的數據,然后調用 SetDlgItemText函數將
所有數據都放置到接收編輯框上。最后一定不要忘記釋放己分配的內存。
另外,為了讓接收編輯框控件支持回車換行,還需要設置其 Multiline屬性。以上就是數據的接收
部分。 
4.實現發送端功能
接下來,編寫發送端程序。雙擊 Chat程序主界面對話框資源上的【發送】按鈕, VC++ 

開發環境將為該按鈕自動生成一個按鈕單擊命令響應函數: OnBtnSend,然后在此函數中添加代碼實

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久亚洲捆绑美女| 亚洲成人av在线电影| 91在线视频免费91| 亚洲国产欧美日韩另类综合| 欧美精品第1页| 99精品一区二区三区| 美洲天堂一区二卡三卡四卡视频| 国产精品视频看| 日韩三级中文字幕| 91久久免费观看| 国产精品亚洲成人| 午夜不卡av免费| 亚洲少妇中出一区| 国产精品久久夜| 亚洲精品一区二区三区福利 | 成人一级视频在线观看| 日韩电影在线观看电影| 亚洲精品免费播放| 国产精品免费视频观看| 久久久精品人体av艺术| 日韩一区二区不卡| 日韩欧美一级在线播放| 欧美久久久久免费| 欧美日韩一区 二区 三区 久久精品 | 国产一区999| 全部av―极品视觉盛宴亚洲| 亚洲成人综合网站| 日韩在线一区二区三区| 五月婷婷综合网| 丝袜亚洲另类丝袜在线| 免费黄网站欧美| 国产一区二区在线观看视频| 久久66热re国产| 高清免费成人av| 99r国产精品| 在线播放中文字幕一区| 欧美tickling挠脚心丨vk| 26uuu另类欧美| 国产精品欧美久久久久无广告| **网站欧美大片在线观看| 一二三区精品福利视频| 日日骚欧美日韩| 国产伦精一区二区三区| 99re在线视频这里只有精品| 欧美日韩一区二区三区四区 | 99re视频精品| 欧美一区二区三区在线电影| 亚洲123区在线观看| 日韩电影一区二区三区四区| 成人丝袜视频网| 国产乱码精品1区2区3区| 国产91色综合久久免费分享| 久久狠狠亚洲综合| 91麻豆swag| 亚洲国产精品av| 欧美aⅴ一区二区三区视频| 成人深夜视频在线观看| 欧美日韩午夜影院| 国产精品久久免费看| 六月丁香综合在线视频| 欧美亚洲丝袜传媒另类| 国产欧美日韩麻豆91| 久久黄色级2电影| 欧美一级二级三级乱码| 亚洲午夜电影网| 欧洲中文字幕精品| 亚洲午夜精品网| 欧美日韩国产一级片| 亚洲二区在线观看| 欧美日本免费一区二区三区| 亚洲丝袜精品丝袜在线| 在线视频欧美精品| 日本不卡中文字幕| 色欧美乱欧美15图片| 国产精品久久久爽爽爽麻豆色哟哟 | 日韩欧美中文字幕公布| 热久久一区二区| 精品久久久久av影院 | 国产精品一区二区在线播放| 久久久夜色精品亚洲| 91小视频免费看| 爽好久久久欧美精品| 国产欧美视频一区二区| 色哟哟亚洲精品| 黄色资源网久久资源365| 国产精品麻豆一区二区| 欧美日韩一区二区三区在线| 国产毛片一区二区| 视频一区二区三区中文字幕| 337p粉嫩大胆噜噜噜噜噜91av| 色综合天天综合网天天看片| 石原莉奈在线亚洲二区| 亚洲欧美成人一区二区三区| 欧美一区2区视频在线观看| 成人黄色国产精品网站大全在线免费观看 | 免费观看久久久4p| 亚洲一二三专区| 国产视频视频一区| 日韩欧美亚洲一区二区| 91在线观看高清| 国产99一区视频免费| 激情综合亚洲精品| 久久www免费人成看片高清| 亚洲一区电影777| 亚洲亚洲精品在线观看| 亚洲欧洲av在线| 成人免费在线视频| 亚洲三级小视频| 日韩美女啊v在线免费观看| 亚洲国产精品高清| 亚洲国产精品精华液2区45| 国产日韩欧美高清在线| 国产精品美女久久久久av爽李琼| 欧美性猛片xxxx免费看久爱| 欧美中文字幕一区| 秋霞国产午夜精品免费视频| 欧美96一区二区免费视频| 日本视频免费一区| 国产乱人伦精品一区二区在线观看| 久久成人麻豆午夜电影| 国产成人小视频| 在线观看国产精品网站| 欧美一级二级三级乱码| 国产肉丝袜一区二区| 国产精品福利一区| 日本亚洲视频在线| 成人午夜av影视| 日韩欧美一区二区三区在线| 国产欧美一区二区精品性色| 一区二区三区小说| 国产伦精品一区二区三区免费迷| av资源网一区| 欧美大片日本大片免费观看| 7777精品伊人久久久大香线蕉的| 精品成人在线观看| 亚洲午夜私人影院| 不卡影院免费观看| 久久夜色精品一区| 精品一二三四区| 欧美三级日韩在线| 综合av第一页| 懂色av一区二区在线播放| 欧美成人aa大片| 五月天激情小说综合| 色综合天天做天天爱| 国产精品看片你懂得| 粉嫩久久99精品久久久久久夜| 日韩一级完整毛片| 蜜臀av性久久久久蜜臀av麻豆| 欧美性大战久久久久久久| 亚洲免费在线看| 在线观看成人免费视频| 亚洲精品成人少妇| 在线免费亚洲电影| 亚洲人快播电影网| 欧美唯美清纯偷拍| 亚洲影视在线播放| 欧美一级高清大全免费观看| 日本不卡不码高清免费观看| 欧美一区二区三区免费| 美女视频黄频大全不卡视频在线播放| 欧美色国产精品| 毛片av一区二区| 中文字幕色av一区二区三区| 99免费精品在线| 日韩国产欧美视频| 国产精品无人区| 欧美日韩精品欧美日韩精品一 | 美女久久久精品| 2020国产成人综合网| 97精品视频在线观看自产线路二| 亚洲欧美中日韩| 欧美一区二区三区性视频| 不卡一区二区三区四区| 青青草精品视频| 一区二区三区在线影院| 在线观看av不卡| 国产在线国偷精品产拍免费yy| 亚洲天堂中文字幕| 精品剧情在线观看| 精品视频在线免费看| 99re亚洲国产精品| 国产精品99精品久久免费| 午夜天堂影视香蕉久久| 亚洲私人影院在线观看| 国产精品久久看| 国产精品丝袜91| 中文字幕在线免费不卡| 久久久久国产精品厨房| 精品国产免费一区二区三区四区 | 日韩一级免费一区| 欧美色精品天天在线观看视频| 99久久精品国产网站| 成人免费观看视频| 成人综合婷婷国产精品久久蜜臀| 久热成人在线视频| 国内久久精品视频| 岛国一区二区在线观看| 不卡视频在线观看| 91国产免费看|