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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? 15.6.3 實(shí)現(xiàn)接收端功能.txt

?? 網(wǎng)上第一本以TXT格式的VC++深入詳解孫鑫的書.全文全以TXT格式,并每一章節(jié)都分了目錄,清晰易讀
?? TXT
字號(hào):
15.6.3 實(shí)現(xiàn)接收端功能
接下來,編寫接收端程序。因?yàn)楫?dāng)在接收端接收數(shù)據(jù)時(shí),如果沒有數(shù)據(jù)到來, recvfrom 函數(shù)會(huì)阻
塞,從而導(dǎo)致程序暫停運(yùn)行。所以,我們可以將接收數(shù)據(jù)的操作放置在一個(gè)單獨(dú)的線程中完成,井
給這個(gè)線程傳遞兩個(gè)參數(shù),一個(gè)是己創(chuàng)建的套接字,一個(gè)是對(duì)話框控件的句柄,這樣,在該線程中,
當(dāng)接收到數(shù)據(jù)后,可以將該數(shù)據(jù)傳回給對(duì)話框,經(jīng)過處理后顯示在接收編輯框控件上。我們可以回
頭看看 CreateThread函數(shù)的聲明,發(fā)現(xiàn)該函數(shù)只為我們提供了一個(gè)參數(shù),即該函數(shù)的第四個(gè)參數(shù),
用來向創(chuàng)建的線程傳遞參數(shù)。而現(xiàn)在我們需要傳遞兩個(gè)參數(shù),這應(yīng)如何實(shí)現(xiàn)呢?"山窮水盡疑無路,
柳暗花明又一村",我們可以看到 CreateThread函數(shù)的第四個(gè)參數(shù)是指針類型,既然是一個(gè)指針,
那么它既可以是一個(gè)指向變量的指針,也可以是一個(gè)指向?qū)ο蟮闹羔槪@樣,我們可以定義一個(gè)結(jié)
構(gòu)體,在該結(jié)構(gòu)體中包含想要傳遞給線程的兩個(gè)參數(shù),然后將該結(jié)構(gòu)體類型的指針變量傳遞給 
CreateThread函數(shù)的第四個(gè)變量。
我們先在 CChatDialog類的頭文件中,在該類的聲明的外部定義一個(gè)阻RECVPARAM結(jié)構(gòu)體,代碼如例 
15-11所示。 
例15-11 

struct  RECVPARAM  

{SOCKET  sock;  //己創(chuàng)建的套接字  
HWND hwnd;  //對(duì)話框句柄 
};

在該結(jié)構(gòu)體中,定義了兩個(gè)成員,一個(gè)是 SOCKET類型的成員: sock,另一個(gè)是HWND類型的成員: hwnd。
	提示:定義結(jié)構(gòu)體時(shí),最后一定要在其后加上分號(hào)。
然后在 CChatDialog類的 OnInitDialog函數(shù)中,在上面剛剛添加的 InitSocket函數(shù)調(diào)用(在上述如
例 15-10所示代碼中加灰顯示的那行代碼)后面添加下述代碼,以完成數(shù)據(jù)接收線程的創(chuàng)建,并傳遞
所需的參數(shù)。
例 15-12 

RECVPARAM *pRecvParam=new RECVPARAM; 
pRecvParam->sock=m_socket; 
pRecvParam->hwnd=m_hWnd; 
//創(chuàng)建接收線程 
HANDLE hThread=CreateThread(NULL, 0, RecvProc , (LPVOID)pRecvParam, 0, NULL) ; 
//關(guān)閉該接收線程句柄,釋放其引用計(jì)數(shù) 
CloseHandle(hThread) ; 
在上述例 15-12所示代碼中,首先定義了一個(gè)阻CVPARAM結(jié)構(gòu)指針: pRecvParam, 并利用 new操作符
為該變量分配空間。然后,對(duì)該結(jié)構(gòu)體變量中的兩個(gè)成員進(jìn)行初始化,將 sock成員設(shè)置為己創(chuàng)建的
套接字,將 hwnd成員設(shè)置為對(duì)話框的句柄。在前面章節(jié)已經(jīng)講過,所有與窗口有關(guān)的類都有一個(gè)數(shù)
據(jù)成員: m_hWnd,它保存了與該類相關(guān)的窗口的句柄。因此, CChatD ialog類的成員變量 mJ1W_hWnd
就是該對(duì)話框的句柄。
接下來,就調(diào)用 CreateThread函數(shù)創(chuàng)建數(shù)據(jù)接收線程,其中第四個(gè)參數(shù)就是主線程要向數(shù)據(jù)接收線
程傳遞的參數(shù),因?yàn)樵搮?shù)的類型是 LPVOID,而我們將要傳遞的卻是 RECVPARAM指針類型,所以需
要進(jìn)行強(qiáng)制轉(zhuǎn)換。
下面,我們要完成數(shù)據(jù)接收線程入口函數(shù)的編寫。我們可以按照本章前面介紹的方法,把線程入口
函數(shù)定義為一個(gè)全局函數(shù),但是在實(shí)際工作中,有些單位要求在面向?qū)ο蟮木幊讨胁荒苁褂萌趾?數(shù),所有的數(shù)據(jù)成員和方法都必須封裝到類中,那么是否可以將線程函數(shù)定義為類的成員函數(shù)呢?
我們可以試驗(yàn)一下,按照前面介紹的線程入口函數(shù)的寫法為 CChatDialog類增加一個(gè)成員函數(shù): 
RecvProc,并在此函數(shù)中添加一條簡(jiǎn)單的 return語句,結(jié)果如例 15-13所示。
例 15-13 

DWORD WINAPI CChatDlg : : RecvProc (LPVOID lpPararneter) 

{ 
return 0 ; 
然后編譯 Chat程序,編譯器將報(bào)告如下錯(cuò)誤: 
D:\VC++深入編程\Chapter15 \Chat\ChatDlg.cpp(123) : error C2664: 'CreateThread': 
cannot 	convert pararneter 3 frorn 'unsigned long (void *)' to 'unsigned long ( stdcall 
*) (void *)' 
None of the functions with this name in scope match the target type 
該錯(cuò)誤是說, CreateThread函數(shù)不能將第三個(gè)參數(shù)從 unsigned long (void *)類型轉(zhuǎn)換為 
unsigned long Lstdcall *)(void *)類型。因?yàn)楫?dāng)創(chuàng)建線程時(shí),系統(tǒng),即運(yùn)行時(shí)代碼會(huì)調(diào)用線程函
數(shù)來啟動(dòng)線程。因?yàn)檫@里的線程函數(shù)是 CChatDialog類的成員函數(shù),為了調(diào)用這個(gè)函數(shù),必須先產(chǎn)
生一個(gè) CChatDialog類的對(duì)象,然后才能調(diào)用該對(duì)象內(nèi)部的成員函數(shù)。然而對(duì)于運(yùn)行時(shí)代碼來說,
它如何知道要產(chǎn)生哪一個(gè)對(duì)象呢?也就是說,運(yùn)行時(shí)根本不知道如何去產(chǎn)生一個(gè) CChatDialog類的對(duì)
象。對(duì)于運(yùn)行時(shí)代碼來說,如果要調(diào)用線程函數(shù)來啟動(dòng)某個(gè)線程的話,應(yīng)該不需要產(chǎn)生某個(gè)對(duì)象就
可以調(diào)用這個(gè)線程函數(shù)。然而這里我們錯(cuò)誤地將這個(gè)線程函數(shù)定義為類的成員函數(shù),所以就出錯(cuò)了。
可以這樣來解決這個(gè)問題:將線程函數(shù)聲明為類的靜態(tài)函數(shù),即在 CChatDialog類的頭文件中,在 
RecvProc函數(shù)的聲明的最前面添加關(guān)鍵詞: static,這時(shí)該函數(shù)的聲明代碼如下所示 : 
static DWORD WINAPI RecvProc(LPVOID lpParameter); 
因?yàn)閷?duì)類的靜態(tài)函數(shù)而言,它不屬于該類的任一個(gè)對(duì)象,它只屬于類本身。所以在 CChatDialog類
的 OnlnitDialog函數(shù)中創(chuàng)建線程時(shí),運(yùn)行時(shí)代碼就可以直接調(diào)用 CChatDialog類的靜態(tài)函數(shù),從而
啟動(dòng)線程。這時(shí)再次編譯 Chat程序,將會(huì)看到程序成功通過。
通過上例說明,如果單位要求采用完全面向?qū)ο蟮乃枷雭砭幊蹋簿褪钦f,不能使用全局函數(shù)和全
局變量了,我們就可以采用靜態(tài)成員函數(shù)和靜態(tài)成員變量的方法來解決上述問題。
下面,為 RecvProc這個(gè)線程入口函數(shù)添加實(shí)現(xiàn)代碼以完成接收數(shù)據(jù)的功能,結(jié)果如例 15-14所示。
例 15-14 


DWORD WINAPI CChatDlg : : RecvProc (LPVOID lpParameter) 
{ 
//獲取主線程傳遞的套接字和窗口句柄 
SOCKET sock=((RECVPARAM*)lpParameter)->sock; 
HWND hwnd=( (RECVPARAM*)lpParameter)->hwnd ; 
delete lpParameter; 
SOCKADDR_IN addrFrom; 
int len=sizeof(SOCKADDR) ; 
char recvBuf[200] ; 
char tempBuf[300] ; 
int retval; 

while (TRUE) 
//接收數(shù)據(jù) 
retval=recvfrom(sock, recvBuf , 200 , 0, (SOCKADDR*)&addrFrom, &len); 
if(SOCKET_ERROR==retval) 
break; 

sprintf(tempBuf , "%s說: %s" , inet_ntoa (addrFrom. sin_addr) , recvBuf); 
::PostMessage(hwnd,WM_RECVDATA , 0, (LPARAM}tempBuf) ; return 0 ; 
在 Recv Proc這個(gè)線程函數(shù)中,首先取出主線程傳遞來的參數(shù),這時(shí)應(yīng)將參數(shù) IpParameter轉(zhuǎn)換為 
RECVPARAM*類型,然后再訪問該結(jié)構(gòu)體中的成員。
接下來就可以調(diào)用 recvfrom函數(shù)接收數(shù)據(jù)了。為了讓接收線程能夠不斷地運(yùn)行,線程函數(shù) RecvProc
進(jìn)行了一個(gè) while循環(huán),在此循環(huán)中不斷地調(diào)用 recvfrom函數(shù)接收數(shù)據(jù),如果該函數(shù)調(diào)用失敗,將
返回 SOCKET ERROR值,那么這時(shí)就調(diào)用 break語旬,終止 while循環(huán):否則返回接收到的字節(jié)數(shù),
這時(shí),可以對(duì)接收到的數(shù)據(jù)進(jìn)行格式化,并將格式化后的數(shù)據(jù)傳遞給對(duì)話框,因?yàn)槲覀円呀?jīng)將對(duì)話
框句柄作為參數(shù)傳遞給線程了,所以可以采用發(fā)送消息的方式將數(shù)據(jù)傳遞給對(duì)話框。本例調(diào)用 
PostMessage函數(shù)向?qū)υ捒虬l(fā)送一條自定義的消息: WM_RECVDATA,將參數(shù) wParam設(shè)置為 0,而將需
要顯示的數(shù)據(jù)作為lParam參數(shù)傳遞,并將該數(shù)據(jù)轉(zhuǎn)換為參數(shù) LParam需要的類型 : LP.ARAM。然后在 
CChatDLg類的頭文件中,定義 WM RECVDATA這個(gè)消息的值,即在該頭文件中添加下面這條語句: 
#define WM_RECVDATA WM_USER+1 
并在 CChatDlg類的頭文件中編寫該消息響應(yīng)函數(shù)原型的聲明,即添加如例 15-15所示代碼中加灰顯
示的那條代碼。讀者應(yīng)注意,前面章節(jié)曾介紹過,在發(fā)送消息時(shí),如果不需要傳遞參數(shù),那么在定
義消息響應(yīng)函數(shù)時(shí)可以沒有參數(shù)。因?yàn)楸纠诎l(fā)送 WM RECVDATA消息時(shí)需要傳遞一個(gè)參數(shù),所以在
定義該消息響應(yīng)函數(shù)時(shí)應(yīng)帶有 wParam和 IParam參數(shù)。
例 15-15 

II Generated message map functions 
11{{AFX_MSG(CChatDlg} 
virtual BOOL OnlnitDialog(} ; 
afx_msg void OnSysCommand(U工 NT nID, LPARAM lParam} ; 
afx_msg void Onpa工 nt ( ) ; 
afx_msg HCURSOR OnQueryDraglcon(}; 

II }}AFX_MSG 
afx_msg void OnRecvData(WPARAM wParam, LPARAM lparam}; DECLARE_MESSAGE_MAP(} 
接下來,在 CChatDIg類的源文件中添加 WM RECVDATA消息映射,即添加如例 15-16所示代碼中加灰
顯示的那條代碼,注意該代碼后不要添加任何標(biāo)點(diǎn)符號(hào)。這里再次提醒讀者,因?yàn)?CAboutDl g類和 
CChatDialog類這兩個(gè)類的實(shí)現(xiàn)代碼在同一個(gè)源文件中,所以一定要看仔細(xì),注意消息映射的位置,
不能寫錯(cuò)位置了。 
BEGIN_MESSAGE_MAP(CChatDlg , CDialog} 11{{AFX_MSG_MAP(CChatDlg} 
ON_WM_SYSCOMMAND() 
ON_WM_PAINT () 
ON_WM_QUERYDRAGICON() 
//}}AFX_MSG_MAP 
ON_MESSAGE(WM_RECVDATA, OnRecvData) 

END_MESSAGE_MAP() 
最后就是該消息響應(yīng)函數(shù)的實(shí)現(xiàn),具體代碼如例 15-17所示。 

例15-17 
//接收數(shù)據(jù)消息響應(yīng)函數(shù)
void CChatDlg : : OnRecvData(WPARAM wParam, LPARAM lParam) 
//取出接收到的數(shù)據(jù) 
CString str=(char*)lParam; 
CString strTemp; 

//獲得己有數(shù)據(jù) 
GetDlgItemText(IDC_EDIT_RECV, strTemp) ; 
str+="\r\n" ; 
str+=strTemp; 

//顯示所有接收到的數(shù)據(jù) 
SetDlgItemText(IDC_ EDIT_RECV, str) ; 
每當(dāng)接收到新的數(shù)據(jù)時(shí),應(yīng)在對(duì)話框中接收編輯框的第一行顯示該數(shù)據(jù),而以前的數(shù)據(jù)應(yīng)依次向下
移動(dòng)。在例 15-17所示OnRecvData函數(shù)中,首先定義了一個(gè)CString類型的變量:str,用來保存從消
息響應(yīng)函數(shù)的lParam參數(shù)取出的數(shù)據(jù),即當(dāng)前接收到的新數(shù)據(jù)。接著又定義了一個(gè) CString類型的
變量: strTemp,用來保存從編輯框控件中獲得的己有文本,即以前接收到的數(shù)據(jù)。該文本的獲得可
以通過調(diào)用GetDlgltemText函數(shù)來實(shí)現(xiàn)。接下來為新收到的數(shù)據(jù)加上換行符:"\r\n",并加上先前己
有的數(shù)據(jù),然后調(diào)用 SetDlgItemText函數(shù),將處理后的數(shù)據(jù)放回到接收數(shù)據(jù)的編輯框中顯示出來。 

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
不卡一区二区三区四区| 亚洲欧美日韩久久| 老司机免费视频一区二区三区| 欧美亚洲另类激情小说| 亚洲成人一区在线| 欧美久久久久久久久久| 久久成人免费网| 久久伊99综合婷婷久久伊| 国产凹凸在线观看一区二区| 国产精品久久久久久久久搜平片| 91理论电影在线观看| 香蕉久久夜色精品国产使用方法 | 欧美精品一区二区不卡| 国产很黄免费观看久久| 自拍偷拍亚洲综合| 欧美视频三区在线播放| 裸体一区二区三区| 中文字幕电影一区| 色丁香久综合在线久综合在线观看| 午夜久久电影网| 日本一区二区三级电影在线观看 | 中文av字幕一区| 色狠狠一区二区| 久久99精品久久久久婷婷| 国产亲近乱来精品视频| 欧美专区日韩专区| 国产一区二区免费在线| 亚洲综合成人在线视频| 欧美xingq一区二区| 99久久婷婷国产精品综合| 天天影视涩香欲综合网| 国产欧美日本一区视频| 欧美二区乱c少妇| 成人自拍视频在线观看| 奇米精品一区二区三区在线观看一| 国产丝袜美腿一区二区三区| 91久久精品网| 国产成人av一区二区三区在线| 亚洲线精品一区二区三区八戒| 久久一区二区三区四区| 欧美日韩激情在线| 成人免费看视频| 日日夜夜免费精品视频| 亚洲丝袜制服诱惑| 久久综合99re88久久爱| 欧美日韩国产综合一区二区三区| 成人永久看片免费视频天堂| 美女视频免费一区| 亚洲午夜av在线| 中文字幕av一区二区三区免费看 | 成人av在线观| 精品影视av免费| 亚洲免费伊人电影| 国产目拍亚洲精品99久久精品| 欧美一激情一区二区三区| 色视频一区二区| 成人h动漫精品一区二区| 麻豆精品视频在线观看视频| 午夜不卡在线视频| 一区二区三区在线视频免费观看| 欧美经典一区二区| 精品免费国产二区三区| 欧美精品亚洲一区二区在线播放| 91丨porny丨蝌蚪视频| 成人污污视频在线观看| 久久精品国产一区二区| 91在线视频在线| 国产高清视频一区| 狠狠色综合播放一区二区| 人人精品人人爱| 日韩精品亚洲一区| 日日摸夜夜添夜夜添国产精品| 亚洲一二三区不卡| 亚洲小说春色综合另类电影| 亚洲精品中文在线| 亚洲免费视频成人| 亚洲欧美另类久久久精品| 中文字幕一区二区三区乱码在线| 日本一区二区三区四区在线视频| 国产无遮挡一区二区三区毛片日本| 久久久不卡影院| 久久精品视频免费观看| 久久久蜜臀国产一区二区| 国产日韩欧美精品在线| 国产丝袜欧美中文另类| 中文字幕一区二区三区在线观看| 中文字幕在线观看不卡| 最新成人av在线| 亚洲麻豆国产自偷在线| 亚洲一区在线观看免费观看电影高清 | 亚洲精选视频免费看| 亚洲日本欧美天堂| 亚洲综合偷拍欧美一区色| 一区二区三区精品视频在线| 亚洲成人一区二区| 久久国产精品一区二区| 国产精品一区二区黑丝| caoporen国产精品视频| 欧美在线免费视屏| 6080午夜不卡| 国产亚洲欧美日韩在线一区| 国产精品情趣视频| 亚洲一区二区av在线| 久久99国内精品| 成人免费视频一区| 欧美亚洲尤物久久| 久久综合资源网| 一区二区三区日韩欧美精品| 亚洲18色成人| 国产成人综合自拍| 欧亚洲嫩模精品一区三区| 日韩一级片网址| 亚洲国产精品成人综合| 亚洲已满18点击进入久久| 美女视频一区二区三区| k8久久久一区二区三区 | 国产精品乱人伦中文| 夜夜亚洲天天久久| 国内久久精品视频| 色噜噜久久综合| 欧美不卡123| 亚洲激情在线激情| 国内成+人亚洲+欧美+综合在线| 91亚洲男人天堂| 精品久久一二三区| 夜夜精品视频一区二区| 国产一区二区精品久久91| 欧美视频日韩视频| 亚洲国产高清aⅴ视频| 日韩—二三区免费观看av| 91网上在线视频| 欧美videossexotv100| 一区二区在线观看视频| 国产成人免费xxxxxxxx| 国产精品传媒入口麻豆| 久久精品国产免费| 欧美综合色免费| 国产精品激情偷乱一区二区∴| 久久国产精品99久久人人澡| 欧美日韩一区二区三区高清| 中文字幕精品一区二区三区精品| 美女网站视频久久| 538在线一区二区精品国产| 亚洲欧美另类综合偷拍| 成人午夜激情影院| 久久久精品综合| 久久国产成人午夜av影院| 制服丝袜亚洲色图| 亚洲一区二区三区四区五区中文| 高清视频一区二区| 久久精品亚洲一区二区三区浴池| 日韩精品亚洲专区| 欧美理论在线播放| 亚洲二区在线视频| 在线观看国产91| 亚洲乱码中文字幕| 91在线观看成人| 国产精品理伦片| 成人午夜精品一区二区三区| 国产亚洲婷婷免费| 国产精品一二三在| 久久婷婷成人综合色| 精东粉嫩av免费一区二区三区| 日韩一区二区在线看| 婷婷夜色潮精品综合在线| 欧美日韩国产片| 亚洲h动漫在线| 欧美一区二区三区在线电影| 天天av天天翘天天综合网色鬼国产| 欧美性色综合网| 日日夜夜精品视频天天综合网| 欧美人妖巨大在线| 日韩黄色免费电影| 日韩欧美国产一二三区| 美女一区二区视频| 91免费小视频| 亚洲自拍另类综合| 91精品国产手机| 精品无码三级在线观看视频| 久久无码av三级| 99久久夜色精品国产网站| 亚洲理论在线观看| 3d成人动漫网站| 国内精品久久久久影院一蜜桃| 国产日韩欧美精品一区| 成人高清在线视频| 亚洲色图在线播放| 欧美精品日韩精品| 激情成人综合网| 国产精品国产a级| 欧美视频一区在线观看| 免费人成精品欧美精品 | 成人av网站大全| 一区二区免费看| 欧美一区二区在线视频| 国产成人综合精品三级| 亚洲另类在线视频| 日韩色在线观看| caoporm超碰国产精品| 午夜国产精品一区|