![Winsocket入門(mén)教程一:多線程阻塞式服務(wù)器和阻塞式客戶端程序(TCP)_第1頁(yè)](http://file4.renrendoc.com/view/f48e8cc6eb8154c3782a6966b432f466/f48e8cc6eb8154c3782a6966b432f4661.gif)
![Winsocket入門(mén)教程一:多線程阻塞式服務(wù)器和阻塞式客戶端程序(TCP)_第2頁(yè)](http://file4.renrendoc.com/view/f48e8cc6eb8154c3782a6966b432f466/f48e8cc6eb8154c3782a6966b432f4662.gif)
![Winsocket入門(mén)教程一:多線程阻塞式服務(wù)器和阻塞式客戶端程序(TCP)_第3頁(yè)](http://file4.renrendoc.com/view/f48e8cc6eb8154c3782a6966b432f466/f48e8cc6eb8154c3782a6966b432f4663.gif)
![Winsocket入門(mén)教程一:多線程阻塞式服務(wù)器和阻塞式客戶端程序(TCP)_第4頁(yè)](http://file4.renrendoc.com/view/f48e8cc6eb8154c3782a6966b432f466/f48e8cc6eb8154c3782a6966b432f4664.gif)
![Winsocket入門(mén)教程一:多線程阻塞式服務(wù)器和阻塞式客戶端程序(TCP)_第5頁(yè)](http://file4.renrendoc.com/view/f48e8cc6eb8154c3782a6966b432f466/f48e8cc6eb8154c3782a6966b432f4665.gif)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Winsocket入門(mén)教程一:多線程阻塞式服務(wù)器和阻塞式客戶端程序(TCP) HYPERLINK JavaScript:d=document;t=d.selection?(d.selection.type!=None?d.selection.createRange().text:):(d.getSelection?d.getSelection():);void(saveit=window.open(/storeit.aspx?t=+escape(d.title)+&u=+escape(d.location.href)+&c=+escape(t),saveit,scrollbars=no,wid
2、th=590,height=300,left=75,top=20,status=no,resizable=yes);saveit.focus(); o 收藏到我的網(wǎng)摘中,并分享給我的朋友 收藏 最近因?yàn)楣ぷ餍枰獙W(xué)習(xí)了Winsocket客戶端服務(wù)器模型程序的設(shè)計(jì)。在學(xué)習(xí)的過(guò)程中,我發(fā)現(xiàn)學(xué)習(xí)Winsocket的資料不多并且十分的零散。我一直沒(méi)有找到一本學(xué)習(xí)Winsocket方面的經(jīng)典國(guó)外著作。而且這些資料中并沒(méi)有提供源代碼文件,所以我只有將這些源代碼在自己敲一遍。在敲代碼的過(guò)程中,我發(fā)現(xiàn)了這些源代碼中的一些錯(cuò)誤的地方和一些已經(jīng)過(guò)時(shí)的Windows程序的輸寫(xiě)方法(Win16?)?,F(xiàn)將學(xué)習(xí)經(jīng)驗(yàn)和通過(guò)閱
3、讀各種資料總結(jié)出來(lái)的模型以及代碼分享出來(lái)。希望對(duì)學(xué)習(xí)Winsocket的初學(xué)者有一定的幫助。 我們首先來(lái)了解一下什么是Winsocket。Winsocket是unix/linux下的berkeley socket在Windows下的實(shí)現(xiàn)。unix/linux下的berkeley socket是網(wǎng)絡(luò)通訊方面的基石,應(yīng)用程序通過(guò)調(diào)用berkeley socket的API進(jìn)行相互通訊,berkeley socket則利用具體的網(wǎng)絡(luò)通訊協(xié)議和操作系統(tǒng)的調(diào)用來(lái)為我們完成具體的通訊工作。Winsocket保留了berkeley socket的所有內(nèi)容,并且為了其能在Win32消息機(jī)制和多線程的環(huán)境下更好的
4、工作。Winsocket在berkeley socket原有的基礎(chǔ)上對(duì)其進(jìn)行了擴(kuò)充。如我們可以利用WSAAsyncSelect對(duì)Socket消息進(jìn)行訂閱,以及使用WSAGetLastError對(duì)多線程環(huán)境下的Winsocket錯(cuò)誤進(jìn)行捕獲。 接著再讓我們來(lái)了解一下服務(wù)器客戶端應(yīng)用程序模型。該模型是構(gòu)建分布式系統(tǒng)的模型之一。服務(wù)器程序一直處于監(jiān)聽(tīng)的狀態(tài),等待客戶端程序的連接。客戶端程序像服務(wù)器程序發(fā)送連接請(qǐng)求,服務(wù)器程序接受該連接請(qǐng)求,同時(shí)與客戶端程序建立連接。此時(shí)客戶端程序就可以向服務(wù)器發(fā)送具體的請(qǐng)求,獲取相關(guān)的數(shù)據(jù)。服務(wù)器客戶端模型有三種連接方式,一種是面向連接的(TCP),面向連接的服務(wù)是
5、一種可靠的服務(wù),它通過(guò)數(shù)據(jù)流進(jìn)行數(shù)據(jù)的傳輸,面向連接的服務(wù)實(shí)現(xiàn)了無(wú)差錯(cuò)無(wú)重復(fù)的順尋數(shù)據(jù)發(fā)送。一種是面向無(wú)連接的(UDP),面向無(wú)連接的服務(wù)是一種不可靠的服務(wù),它通過(guò)數(shù)據(jù)報(bào)進(jìn)行數(shù)據(jù)傳輸,由于數(shù)據(jù)報(bào)進(jìn)行傳輸時(shí)的順序是無(wú)序的,所以它是不可靠的服務(wù)。最后一種是多播的方式,及服務(wù)器程序主動(dòng)向多個(gè)客戶端程序發(fā)送信息。面向連接的服務(wù)器客戶端應(yīng)用程序模型的程序流程圖如下所示:在此模型的阻塞模式中,服務(wù)端程序在執(zhí)行accept操作、客戶端程序connect操作、以及服務(wù)端客戶端在進(jìn)行read和write操作時(shí),如果這些操作既沒(méi)有成功也沒(méi)有失敗,應(yīng)用程序會(huì)在執(zhí)行這些操作的地方一直阻塞著。所以我們應(yīng)該在服務(wù)端應(yīng)用程
6、序的主線程中不停的調(diào)用accept操作,以使服務(wù)端程序能不停地接受客戶端程序發(fā)送過(guò)來(lái)的連接請(qǐng)求。而在接受了一個(gè)客戶端的連接請(qǐng)求后,我們應(yīng)改為每一個(gè)接受的連接請(qǐng)求開(kāi)辟一個(gè)專(zhuān)門(mén)的線程來(lái)接受客戶端程序發(fā)送的請(qǐng)求以及為具體的請(qǐng)求返回特定的信息。 根據(jù)以上的程序流程圖以及說(shuō)明,我們可以寫(xiě)出以下的服務(wù)端程序源代碼: HYPERLINK /shining100/archive/2010/05/09/5571644.aspx view plain HYPERLINK /shining100/archive/2010/05/09/5571644.aspx copy to clipboard HYPERLINK
7、/shining100/archive/2010/05/09/5571644.aspx print HYPERLINK /shining100/archive/2010/05/09/5571644.aspx ?/ /fileServerMultThreadServerMultThread.cpp / /brief阻塞式多線程服務(wù)器程序。每當(dāng)客戶端程序請(qǐng)求與服務(wù)端連接時(shí),服務(wù)端程序開(kāi)放一個(gè)線程接受客戶端程序的請(qǐng)求 /并且向客戶端回饋請(qǐng)求的信息。客戶端請(qǐng)求的信息輸出到控制臺(tái)中. / #include #include #include #include #pragmacomment(lib,ws2
8、_32.lib) #defineASSERTassert #defineTHREADHANDLE #defineEVENTHANDLE #defineCloseThreadCloseHandle #defineCloseEventCloseHandle usingstd:cin; usingstd:cout; usingstd:endl; / /structtagServerRecv / /brief線程函數(shù)參數(shù)結(jié)構(gòu)體,其中包含已建立連接的socket. / /authorShining100 /date2010-05-18 / typedefstructtagServerRecv SOCKE
9、TskAccept;/已建立連接的socket CRITICAL_SECTION*pcs;/同步控制臺(tái)輸出的臨界區(qū) EVENTe;/保證結(jié)構(gòu)體各個(gè)字段在結(jié)構(gòu)體字段改變之前將其拷貝到線程中的信號(hào)量 THREADt;/當(dāng)前線程的內(nèi)核對(duì)象 DWORDdwThreadID;/當(dāng)前線程的ID SERVER_RECV,*PSERVER_RECV; / /fnstaticintServerRecv(LPVOIDlParam) / /brief服務(wù)器與建立連接的客戶端進(jìn)行通訊. / /authorShining100 /date2010-05-18 / /paramlParam線程函數(shù)參數(shù),詳細(xì)信息見(jiàn)上面說(shuō)明
10、. / /return總是返回0. / staticintServerRecv(LPVOIDlParam); staticconstintc_iPort=10001; intmain() intiRet=SOCKET_ERROR; /初始化Winsocket,所有Winsocket程序必須先使用WSAStartup進(jìn)行初始化 WSADATAdata; ZeroMemory(&data,sizeof(WSADATA); iRet=WSAStartup(MAKEWORD(2,0),&data); ASSERT(SOCKET_ERROR!=iRet); /建立服務(wù)端程序的監(jiān)聽(tīng)套接字 SOCKETsk
11、Listen=INVALID_SOCKET; skListen=socket(AF_INET,SOCK_STREAM,0); ASSERT(INVALID_SOCKET!=skListen); /初始化監(jiān)聽(tīng)套接字地址信息 sockaddr_inadrServ;/表示網(wǎng)絡(luò)地址 ZeroMemory(&adrServ,sizeof(sockaddr_in); adrServ.sin_family=AF_INET;/初始化地址格式,只能為AF_INET adrServ.sin_port=htons(c_iPort);/初始化端口,由于網(wǎng)絡(luò)字節(jié)順序和主機(jī)字節(jié)順序相反,所以必須使用htons將主機(jī)字節(jié)順
12、序轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)順序 adrServ.sin_addr.s_addr=INADDR_ANY;/初始化IP,由于是服務(wù)器程序,所以可以將INADDR_ANY賦給該字段,表示任意的IP /綁定監(jiān)聽(tīng)套接字到本地 iRet=bind(skListen,(sockaddr*)&adrServ,sizeof(sockaddr_in); ASSERT(SOCKET_ERROR!=iRet); /使用監(jiān)聽(tīng)套接字進(jìn)行監(jiān)聽(tīng) iRet=listen(skListen,SOMAXCONN);/SOMAXCONN表示可以連接到該程序的最大連接數(shù) ASSERT(SOCKET_ERROR!=iRet); /輸出控制臺(tái)緩沖區(qū)
13、,由于可能有多個(gè)客戶端程序可能同時(shí)向緩沖區(qū)發(fā)送請(qǐng)求信息 /為了保證輸出時(shí)能夠一次性完整的輸出完一個(gè)客戶端的請(qǐng)求信息,所以在輸出客 /戶程序的信息到控制臺(tái)時(shí),必須使用臨界區(qū)阻塞其它線程 CRITICAL_SECTIONcs; InitializeCriticalSection(&cs); /保證結(jié)構(gòu)體各個(gè)字段在結(jié)構(gòu)體字段改變之前將其拷貝到線程中的信號(hào)量 /因?yàn)楫?dāng)該結(jié)構(gòu)體拷貝到線程中之前,有可能有新的連接到來(lái)并改變了結(jié)構(gòu)體的值 /所以我們必須先保證值拷貝過(guò)后再接受連接 EVENTe=NULL; e=CreateEvent(NULL,FALSE,FALSE,NULL); ASSERT(NULL!=e
14、); for(;) /客戶端向服務(wù)器端發(fā)送連接請(qǐng)求,服務(wù)器端接受客戶端的連接 SOCKETskAccept=INVALID_SOCKET; sockaddr_inadrClit; ZeroMemory(&adrClit,sizeof(sockaddr_in); intiLen=sizeof(sockaddr_in); skAccept=accept(skListen,(sockaddr*)&adrClit,&iLen);/如果沒(méi)有客戶端程序請(qǐng)求連接,服務(wù)端程序會(huì)一直阻塞在這里等待連接 ASSERT(INVALID_SOCKET!=skAccept); SERVER_RECVsr; /成功創(chuàng)建連
15、接后創(chuàng)建一個(gè)獨(dú)立的線程應(yīng)答客戶請(qǐng)求,以防止應(yīng)用程序因?yàn)樽枞麩o(wú)法應(yīng)答新的客戶請(qǐng)求 /我們應(yīng)該先將線程掛起,以便我們能夠在線程執(zhí)行之前初始化線程所需要的結(jié)構(gòu)體變量中的各個(gè)字段 THREADhThread=NULL; DWORDdwThreadID=0; hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ServerRecv, &sr,CREATE_SUSPENDED,&dwThreadID); ASSERT(NULL!=hThread); /初始化結(jié)構(gòu)體字段 sr.skAccept=skAccept; sr.pcs=&cs; sr.e=e; s
16、r.t=hThread; sr.dwThreadID=dwThreadID; /啟動(dòng)線程 DWORDdwRet=ResumeThread(hThread); ASSERT(-1!=dwRet); /保證結(jié)構(gòu)體被拷貝到線程中后再應(yīng)答新的連接 dwRet=WaitForSingleObject(e,INFINITE); ASSERT(WAIT_FAILED!=dwRet); /清理線程同步資源 DeleteCriticalSection(&cs); BOOLbRet=FALSE; bRet=CloseEvent(e); ASSERT(bRet); /關(guān)閉該套接字的連接 iRet=shutdown(
17、skListen,SD_SEND); ASSERT(SOCKET_ERROR!=iRet); /清理該套接字的資源 iRet=closesocket(skListen); ASSERT(SOCKET_ERROR!=iRet); /清理Winsocket資源 iRet=WSACleanup(); ASSERT(SOCKET_ERROR!=iRet); cin.get(); return0; intServerRecv(LPVOIDlParam) /拷貝結(jié)構(gòu)體各個(gè)字段到線程中 PSERVER_RECVpsr=(PSERVER_RECV)lParam; SERVER_RECVsr= psr-skAc
18、cept, psr-pcs, psr-e, psr-t, psr-dwThreadID ; /設(shè)置信號(hào)量,使主線程能夠接受新的連接 BOOLbRet=FALSE; bRet=SetEvent(sr.e); ASSERT(bRet); constintc_iBufLen=512; charszBufc_iBufLen+1=0; constcharc_szPrefix=Serverrecv:; constintc_iPrefLen=strlen(c_szPrefix); charszRelyc_iBufLen+16+1=0; strcpy(szRely,c_szPrefix); intiRet=S
19、OCKET_ERROR; for(;) iRet=recv(sr.skAccept,szBuf,c_iBufLen,0);/接收客戶端發(fā)送的信息,如果客戶端不發(fā)送信息,則線程會(huì)阻塞到此處 if(0=iRet)/客戶端優(yōu)雅的關(guān)閉了此連接 coutConnectionsr.dwThreadIDshutdown.endl; break; elseif(SOCKET_ERROR=iRet)/客戶端粗魯?shù)年P(guān)閉了此連接或者接受信息出錯(cuò) coutConnectionsr.dwThreadIDrecverror.endl; break; szBufiRet=0; EnterCriticalSection(sr
20、.pcs); coutConnectionsr.dwThreadIDsays:szBufendl;/輸出接收到的信息 LeaveCriticalSection(sr.pcs); /向客戶端發(fā)送信息 strcpy(szRely+c_iPrefLen,szBuf); iRet=send(sr.skAccept,szRely,strlen(szRely),0);/客戶端如果沒(méi)有足夠的緩沖區(qū)接受信息,則線程會(huì)阻塞到此處 if(SOCKET_ERROR=iRet) coutConnectionsr.dwThreadIDsenderror.0); ASSERT(SOCKET_ERROR!=iRet); /
21、清理該套接口的資源 iRet=closesocket(sr.skAccept); ASSERT(SOCKET_ERROR!=iRet); /關(guān)閉該線程對(duì)象 bRet=CloseThread(sr.t); ASSERT(bRet); coutConnectionsr.dwThreadIDexit.endl; return0; HTMLCONTROL Forms.HTML:TextArea.1 在用Winsocket編寫(xiě)程序時(shí),我們首先必須要進(jìn)行如下的操作,以為該進(jìn)程初始化Winsocket和Ws2_32.dll,而使后面的函數(shù)調(diào)用有效。 HYPERLINK /shining100/archive
22、/2010/05/09/5571644.aspx view plain HYPERLINK /shining100/archive/2010/05/09/5571644.aspx copy to clipboard HYPERLINK /shining100/archive/2010/05/09/5571644.aspx print HYPERLINK /shining100/archive/2010/05/09/5571644.aspx ?WSADATAdata; ZeroMemory(&data,sizeof(WSADATA); iRet=WSAStartup(MAKEWORD(2,0),
23、&data); ASSERT(SOCKET_ERROR!=iRet); HTMLCONTROL Forms.HTML:TextArea.1 WSAStartup第一個(gè)參數(shù)為要使用的Winsocket的版本,MAKEWORD(2, 0)表示我們使用Winsocket2.0。第二個(gè)參數(shù)在WSAStartup初始化后,可以獲得一些Winsocket相關(guān)信息,如該版本W(wǎng)insocket所支持的最大socket數(shù)量以及UDP包的最大大小。 在初始化了Winsocket后,我們就可以創(chuàng)建一個(gè)socket監(jiān)聽(tīng)客戶端的連接請(qǐng)求了。 HYPERLINK /shining100/archive/2010/05/0
24、9/5571644.aspx view plain HYPERLINK /shining100/archive/2010/05/09/5571644.aspx copy to clipboard HYPERLINK /shining100/archive/2010/05/09/5571644.aspx print HYPERLINK /shining100/archive/2010/05/09/5571644.aspx ?SOCKETskListen=INVALID_SOCKET; skListen=socket(AF_INET,SOCK_STREAM,0); ASSERT(INVALID_S
25、OCKET!=skListen); HTMLCONTROL Forms.HTML:TextArea.1 socket函數(shù)分配相應(yīng)的資源并將該socket綁定到一個(gè)特定的傳輸服務(wù)提供者。socket的第一個(gè)參數(shù)為網(wǎng)絡(luò)地址族,該參數(shù)只能為AF_INET,第二個(gè)參數(shù)可以為SOCK_STREAM或者SOCK_DGRAM。SOCK_STREAM為一個(gè)流式套接口,它提供雙向可靠、面向連接的TCP服務(wù)。SOCK_DGRAM為一個(gè)數(shù)據(jù)報(bào)套接口,它提供不可靠、面向無(wú)連接的UDP服務(wù)。第三個(gè)參數(shù)一般選擇為0,表示由Winsocket選擇具體的協(xié)議使用。 在建立了一個(gè)監(jiān)聽(tīng)socket后,我們就可以將該套接口與本地地
26、址進(jìn)行綁定,已將其設(shè)置成為網(wǎng)絡(luò)中一個(gè)獨(dú)一無(wú)二的地址。 HYPERLINK /shining100/archive/2010/05/09/5571644.aspx view plain HYPERLINK /shining100/archive/2010/05/09/5571644.aspx copy to clipboard HYPERLINK /shining100/archive/2010/05/09/5571644.aspx print HYPERLINK /shining100/archive/2010/05/09/5571644.aspx ?iRet=bind(skListen,(s
27、ockaddr*)&adrServ,sizeof(sockaddr_in); ASSERT(SOCKET_ERROR!=iRet); HTMLCONTROL Forms.HTML:TextArea.1 在綁定了本地地址后,我們就可以將該socket設(shè)置為監(jiān)聽(tīng)狀態(tài),以使該socket可以檢測(cè)到來(lái)自客戶端程序的連接請(qǐng)求。 HYPERLINK /shining100/archive/2010/05/09/5571644.aspx view plain HYPERLINK /shining100/archive/2010/05/09/5571644.aspx copy to clipboard HYP
28、ERLINK /shining100/archive/2010/05/09/5571644.aspx print HYPERLINK /shining100/archive/2010/05/09/5571644.aspx ?iRet=listen(skListen,SOMAXCONN);/SOMAXCONN表示可以連接到該程序的最大連接數(shù) ASSERT(SOCKET_ERROR!=iRet); HTMLCONTROL Forms.HTML:TextArea.1 接下來(lái)我們我們就可以利用套接口接受來(lái)自客戶端程序的連接了。我們以該套接口為參數(shù)調(diào)用accept函數(shù),accept函數(shù)調(diào)用成功后,將建立
29、一個(gè)可以接受和發(fā)送數(shù)據(jù)的套接口skAccept。 HYPERLINK /shining100/archive/2010/05/09/5571644.aspx view plain HYPERLINK /shining100/archive/2010/05/09/5571644.aspx copy to clipboard HYPERLINK /shining100/archive/2010/05/09/5571644.aspx print HYPERLINK /shining100/archive/2010/05/09/5571644.aspx ?/客戶端向服務(wù)器端發(fā)送連接請(qǐng)求,服務(wù)器端接受客
30、戶端的連接 SOCKETskAccept=INVALID_SOCKET; sockaddr_inadrClit; ZeroMemory(&adrClit,sizeof(sockaddr_in); intiLen=sizeof(sockaddr_in); skAccept=accept(skListen,(sockaddr*)&adrClit,&iLen);/如果沒(méi)有客戶端程序請(qǐng)求連接,服務(wù)端程序會(huì)一直阻塞在這里等待連接 ASSERT(INVALID_SOCKET!=skAccept); HTMLCONTROL Forms.HTML:TextArea.1 在成功的建立了新套接口后,我們就可以利用
31、該套接口在我們的線程函數(shù)中接收和發(fā)送數(shù)據(jù)了。 HYPERLINK /shining100/archive/2010/05/09/5571644.aspx view plain HYPERLINK /shining100/archive/2010/05/09/5571644.aspx copy to clipboard HYPERLINK /shining100/archive/2010/05/09/5571644.aspx print HYPERLINK /shining100/archive/2010/05/09/5571644.aspx ?iRet=recv(sr.skAccept,szB
32、uf,c_iBufLen,0);/接收客戶端發(fā)送的信息,如果客戶端不發(fā)送信息,則線程會(huì)阻塞到此處 if(0=iRet)/客戶端優(yōu)雅的關(guān)閉了此連接 coutConnectionsr.dwThreadIDshutdown.endl; break; elseif(SOCKET_ERROR=iRet)/客戶端粗魯?shù)年P(guān)閉了此連接或者接受信息出錯(cuò) coutConnectionsr.dwThreadIDrecverror.endl; break; szBufiRet=0; HTMLCONTROL Forms.HTML:TextArea.1 HYPERLINK /shining100/archive/2010
33、/05/09/5571644.aspx view plain HYPERLINK /shining100/archive/2010/05/09/5571644.aspx copy to clipboard HYPERLINK /shining100/archive/2010/05/09/5571644.aspx print HYPERLINK /shining100/archive/2010/05/09/5571644.aspx ?strcpy(szRely+c_iPrefLen,szBuf); iRet=send(sr.skAccept,szRely,strlen(szRely),0);/客
34、戶端如果沒(méi)有足夠的緩沖區(qū)接受信息,則線程會(huì)阻塞到此處 if(SOCKET_ERROR=iRet) coutConnectionsr.dwThreadIDsenderror.0); ASSERT(SOCKET_ERROR!=iRet); /清理該套接口的資源 iRet=closesocket(sr.skAccept); ASSERT(SOCKET_ERROR!=iRet); HTMLCONTROL Forms.HTML:TextArea.1 監(jiān)聽(tīng)socket的關(guān)閉也與上面套接口關(guān)閉的方法一致。在關(guān)閉了監(jiān)聽(tīng)套接口后,我們的服務(wù)器程序應(yīng)該調(diào)用WSACleanup函數(shù),已完成對(duì)Winsocket和ws
35、2_32.dll的清理。上述就是該類(lèi)型服務(wù)器程序應(yīng)用程序執(zhí)行的全過(guò)程了??蛻舳顺绦虻拇a跟服務(wù)器程序的代碼相似,程序代碼如下所示: HYPERLINK /shining100/archive/2010/05/09/5571644.aspx view plain HYPERLINK /shining100/archive/2010/05/09/5571644.aspx copy to clipboard HYPERLINK /shining100/archive/2010/05/09/5571644.aspx print HYPERLINK /shining100/archive/2010/05
36、/09/5571644.aspx ?/ /fileClientBlockClientBlock.cpp / /brief連接服務(wù)器并向服務(wù)器發(fā)送信息,然后接受服務(wù)器發(fā)送的信息. / #include #include #include #pragmacomment(lib,ws2_32.lib) #defineASSERTassert usingstd:cin; usingstd:cout; usingstd:endl; staticconstcharc_szIP=; staticconstintc_iPort=10001; intmain() intiRet=SOCKET_ERROR; /初
37、始化Winsocket,所有Winsocket程序必須先使用WSAStartup進(jìn)行初始化 WSADATAdata; ZeroMemory(&data,sizeof(WSADATA); iRet=WSAStartup(MAKEWORD(2,0),&data); ASSERT(SOCKET_ERROR!=iRet); /建立連接套接字 SOCKETskClient=INVALID_SOCKET; skClient=socket(AF_INET,SOCK_STREAM,0); ASSERT(INVALID_SOCKET!=skClient); /初始化連接套接字地址信息 sockaddr_inad
38、rServ;/表示網(wǎng)絡(luò)地址 ZeroMemory(&adrServ,sizeof(sockaddr_in); adrServ.sin_family=AF_INET;/初始化地址格式,只能為AF_INET adrServ.sin_port=htons(c_iPort);/初始化端口,由于網(wǎng)絡(luò)字節(jié)順序和主機(jī)字節(jié)順序相反,所以必須使用htons將主機(jī)字節(jié)順序轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)順序 adrServ.sin_addr.s_addr=inet_addr(c_szIP);/初始化IP,由于網(wǎng)絡(luò)字節(jié)順序和主機(jī)字節(jié)順序相反,所以必須使用inet_addr將主機(jī)字節(jié)順序轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)順序 /使用連接套接字進(jìn)行連接 i
39、Ret=connect(skClient,(sockaddr*)&adrServ,sizeof(sockaddr_in); ASSERT(SOCKET_ERROR!=iRet); constintc_iBufLen=512; charszBufc_iBufLen+16+1=0; for(;) coutszBuf; if(0=strcmp(exit,szBuf) break; /向服務(wù)器端發(fā)送信息 iRet=send(skClient,szBuf,strlen(szBuf),0);/服務(wù)器端如果沒(méi)有足夠的緩沖區(qū)接受信息,則線程會(huì)阻塞到此處 if(SOCKET_ERROR=iRet) coutsenderror.endl; break; /接收服務(wù)器端發(fā)送的信息 iRet=recv(s
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 合法的金融借款合同
- 出租房租賃合同協(xié)議
- 用于經(jīng)營(yíng)的房屋租賃合同
- 大數(shù)據(jù)風(fēng)控服務(wù)合同
- 汽車(chē)租賃書(shū)面合同書(shū)
- 聯(lián)保借款標(biāo)準(zhǔn)合同
- 2025小麥購(gòu)銷(xiāo)合同樣本
- 個(gè)人借款合同合同英文范本
- 提升銷(xiāo)售技巧的培訓(xùn)課程
- 2024年5G通信基礎(chǔ)設(shè)施建設(shè)合同
- 2025年護(hù)士資格考試必考基礎(chǔ)知識(shí)復(fù)習(xí)題庫(kù)及答案(共250題)
- 2025年人教版PEP二年級(jí)英語(yǔ)上冊(cè)階段測(cè)試試卷
- 煙草業(yè)產(chǎn)業(yè)鏈協(xié)同創(chuàng)新模式-洞察分析
- 經(jīng)濟(jì)學(xué)基礎(chǔ)試題及答案 (二)
- 2024-2030年中國(guó)蠔肉市場(chǎng)發(fā)展前景調(diào)研及投資戰(zhàn)略分析報(bào)告
- GB 19053-2024殯儀場(chǎng)所致病菌安全限值
- 寧騷公共政策學(xué)完整版筆記
- 2023年湖南高速鐵路職業(yè)技術(shù)學(xué)院高職單招(數(shù)學(xué))試題庫(kù)含答案解析
- 勇者斗惡龍9(DQ9)全任務(wù)攻略
- 經(jīng)顱磁刺激的基礎(chǔ)知識(shí)及臨床應(yīng)用參考教學(xué)課件
- 小學(xué)語(yǔ)文人教四年級(jí)上冊(cè)第四單元群文閱讀“神話故事之人物形象”P(pán)PT
評(píng)論
0/150
提交評(píng)論