第3講 流式套接字_第1頁
第3講 流式套接字_第2頁
第3講 流式套接字_第3頁
第3講 流式套接字_第4頁
第3講 流式套接字_第5頁
已閱讀5頁,還剩44頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

網(wǎng)絡(luò)編程技術(shù)

第三講流式套接字Outline2023/2/31TCP:傳輸控制協(xié)議流式套接字編程模型基本函數(shù)程序舉例Outline2023/2/32TCP:傳輸控制協(xié)議流式套接字編程模型基本函數(shù)程序舉例TransportControlProtocol,傳輸控制協(xié)議面向連接提供高可靠性服務(wù),用于一次傳輸要交換大量報(bào)文的情形。增加許多開銷:確認(rèn)、流量控制、計(jì)時(shí)器以及連接管理等。2023/2/33傳輸層協(xié)議TCP2023/2/34TCP正常的連接與關(guān)閉SYN,SEQ=x客戶進(jìn)程服務(wù)器進(jìn)程LISTEN(被動(dòng)打開)(主動(dòng)打開)SYN_SENTSYN_RCVDESTABLISHEDESTABLISHED(主動(dòng)關(guān)閉)FIN_WAIT_1CLOSE_WAIT(被動(dòng)關(guān)閉)FIN_WAIT_2LAST_ACKTIME_WAITCLOSED(全雙工數(shù)據(jù)傳送階段)SYN,ACK,SEQ=y,ACK=x+1ACK,SEQ=x+1,ACK=y+1FIN,SEQ=uACK,SEQ=v,ACK=u+1FIN,ACK,SEQ=v,ACK=u+1ACK,SEQ=u+1,ACK=v+1TIME_WAITCLOSE_WAITSYN_RCVDESTABLISHED5CLOSEDESTABLISHEDLISTENCLOSE_WAITFIN_WAIT_1SYN_RCVDFIN_WAIT_2CLOSINGTIME_WAITSYN_SENTLAST_ACK主動(dòng)打開被動(dòng)打開被動(dòng)關(guān)閉主動(dòng)關(guān)閉起點(diǎn)被動(dòng)打開主動(dòng)打開發(fā)送SYN同時(shí)打開收到SYN,發(fā)送SYN,ACK收到ACK數(shù)據(jù)傳送階段

關(guān)閉發(fā)送FIN

關(guān)閉發(fā)送FIN

關(guān)閉發(fā)送FIN收到RST

收到SYN發(fā)送SYN,ACK

關(guān)閉或超時(shí)收到ACK

收到SYN,ACK發(fā)送ACK收到ACK收到ACK收到FIN發(fā)送ACK收到FIN,ACK

發(fā)送ACK收到FIN發(fā)送ACK同時(shí)關(guān)閉收到FIN發(fā)送ACK發(fā)送SYN定時(shí)經(jīng)過兩倍報(bào)文段壽命后關(guān)閉TCP

態(tài)

機(jī)Outline2023/2/36TCP:傳輸控制協(xié)議流式套接字編程模型基本函數(shù)程序舉例傳輸方式客戶機(jī)/服務(wù)器方式特點(diǎn)面向連接過程服務(wù)器進(jìn)程和客戶端進(jìn)程在通信前必須創(chuàng)建各自的套接字,建立連接,然后對(duì)相應(yīng)的套接字進(jìn)行“讀”、“寫”操作,實(shí)現(xiàn)數(shù)據(jù)的傳輸。適用場(chǎng)合:大數(shù)據(jù)量可靠性要求高廣域網(wǎng)2023/2/37流式套接字編程模型基礎(chǔ)服務(wù)器通信過程:socket初始化;創(chuàng)建套接字,指定使用TCP(可靠的傳輸服務(wù))進(jìn)行通信;指定本地地址和通信端口;等待客戶端的連接請(qǐng)求;進(jìn)行數(shù)據(jù)傳輸;關(guān)閉套接字;結(jié)束對(duì)windowssocketsdll的使用。2023/2/38通信過程客戶端通信過程:socket初始化;創(chuàng)建套接字,指定使用TCP(可靠的傳輸服務(wù))進(jìn)行通信;指定服務(wù)器地址和通信端口;向服務(wù)器發(fā)送連接請(qǐng)求;進(jìn)行數(shù)據(jù)傳輸;關(guān)閉套接字;結(jié)束對(duì)windowssocketsdll的使用。2023/2/39通信過程10客戶/服務(wù)器交互模型socket(),建立流式套接字,返回套接字標(biāo)識(shí)s

bind(),使套接字s與本地地址相連listen(),在套接字s上偵聽連接請(qǐng)求accept(),準(zhǔn)備接收客戶連接;accept返回,創(chuàng)建新套接字ns,原套接字s仍處于偵聽狀態(tài);socket(),建立流式套接字,返回套接字標(biāo)識(shí)s

connect(),s與服務(wù)器建立連接recv/send(),在ns上讀寫數(shù)據(jù)closesocket(),關(guān)閉s,通信結(jié)束closesocket(),關(guān)閉套接字nsclosesocket(),關(guān)閉套接字s,服務(wù)結(jié)束服務(wù)器客戶端recv/send(),在s上讀寫數(shù)據(jù)為什么客戶端沒有bind,而服務(wù)器端需要?客戶端的套接字如何獲得端點(diǎn)地址?應(yīng)用如何獲知自己當(dāng)前的主機(jī)地址和端口號(hào)?server如何處理與多個(gè)client建立連接?2023/2/311客戶/服務(wù)器交互模型2023/2/312流式套接字服務(wù)器工作原理ListeningserverTCPServerchildServerchildclientclientTCPTCPconnectionconnectionconnectionconnectionconnectionconnectionOutline2023/2/313TCP:傳輸控制協(xié)議流式套接字編程模型基本函數(shù)程序舉例函數(shù)定義:SOCKETsocket(intaf,inttype,intprotocol);

輸入?yún)?shù):af:指定網(wǎng)絡(luò)地址類型,一般取AF_INET,表示該套接字在Internet域中進(jìn)行通信;type:指定套接字類型,這里取SOCK_STREAM,表示創(chuàng)建的套接字是流套接字;protocol:指定網(wǎng)絡(luò)協(xié)議,取0表示默認(rèn)為TCP/IP協(xié)議。返回值:正確:創(chuàng)建的套接字句柄SOCKET錯(cuò)誤:INVALID_SOCKET(WSAGetLastError)功能:創(chuàng)建一個(gè)套接字,用于以后的數(shù)據(jù)傳輸說明:該函數(shù)調(diào)用指定了五元組中的“協(xié)議”一元。服務(wù)器和客戶端都要?jiǎng)?chuàng)建,服務(wù)器總是先于客戶進(jìn)程啟動(dòng)。2023/2/314①創(chuàng)建套接字——socket()AF_XXX與PF_XXXAF_前綴表示地址族,PF_前綴表示協(xié)議族。目前頭文件(socket.h)中為一給定協(xié)議定義的PF_值總是與此協(xié)議的AF_值相等。盡管這種相等關(guān)系并不保證永遠(yuǎn)正確,若有人試圖給已有的協(xié)議改變這種約定,則許多現(xiàn)存代碼都將崩潰,目前兩個(gè)值混用現(xiàn)象比較多。2023/2/315①創(chuàng)建套接字——socket()函數(shù)定義:intbind(SOCKETs,conststructsockaddr*name,intnamelen);輸入?yún)?shù):s:標(biāo)識(shí)一個(gè)未捆綁套接字的句柄,用來等待客戶機(jī)的連接;name:賦予套接字的地址,由structsockaddr結(jié)構(gòu)表示;namelen:name字段的值長(zhǎng)度,以字節(jié)為單位。返回值:正確:0錯(cuò)誤:SOCKET_ERROR(WSAGetLastError)功能:將本地地址綁定到所創(chuàng)建的套接字上以在網(wǎng)絡(luò)上標(biāo)識(shí)該套接字。2023/2/316②指定本地地址——bind()地址種類常規(guī)地址:特定主機(jī)地址,特定端口號(hào)通配地址:INADDR_ANY,02023/2/317關(guān)于bind函數(shù)的幾點(diǎn)說明進(jìn)程指定結(jié)果IP地址端口通配地址0內(nèi)核選擇IP和端口通配地址非0內(nèi)核選擇IP,進(jìn)程指定端口本地IP地址0進(jìn)程指定IP,內(nèi)核選擇端口本地IP地址非0進(jìn)程指定IP和端口When?client端的socket是否需要關(guān)聯(lián)本地地址的?不建議connectsendto如果由系統(tǒng)選擇地址或端口,如何獲得套接字的雙方地址?Getsockname函數(shù):獲得本地與套接字關(guān)聯(lián)的IP地址和端口號(hào)Getpeername函數(shù):獲得通信對(duì)等端與套接字關(guān)聯(lián)的IP地址和端口號(hào)2023/2/318關(guān)于bind函數(shù)的幾點(diǎn)說明函數(shù)定義:intlisten(SOCKETs,intbacklog)輸入?yún)?shù):s:一個(gè)本地已建立的、尚未連接的套接字標(biāo)識(shí);backlog:表示請(qǐng)求隊(duì)列的最大長(zhǎng)度,BSD4.2允許的最大值為5;返回值:正確:0錯(cuò)誤:SOCKET_ERROR功能:把一個(gè)未連接的套接字轉(zhuǎn)換成一個(gè)被動(dòng)套接字;規(guī)定了內(nèi)核相應(yīng)套接字排隊(duì)的最大連接個(gè)數(shù)。2023/2/319③監(jiān)聽連接——listen()2023/2/320服務(wù)器初始化操作系統(tǒng)Web服務(wù)器2.bind(80)801.socket()3.listen()Listenqueue2023/2/321未完成連接隊(duì)列(SYN_RCVD狀態(tài))已完成連接隊(duì)列(ESTABLISHED狀態(tài))服務(wù)器TCP到達(dá)的SYN分節(jié)三次握手完成accept兩隊(duì)列之和不超過backlogSYN,SEQ=x客戶進(jìn)程服務(wù)器進(jìn)程(主動(dòng)打開)SYN_SENTSYN_RCVDESTABLISHEDESTABLISHEDSYN,ACK,SEQ=y,ACK=x+1ACK,SEQ=x+1,ACK=y+1SYN_RCVDESTABLISHED函數(shù)定義:intconnect(SOCKETs,structsockaddrFAR*name,intnamelen)輸入?yún)?shù):s:本地套接字標(biāo)識(shí)name:要建立連接的遠(yuǎn)地地址和端口namelen:指明name的長(zhǎng)度返回值:正確:0錯(cuò)誤:SOCKET_ERROR2023/2/322④客戶端建立套接字連接——connect()2023/2/323建立與服務(wù)器的連接OS1.socket()Web服務(wù)器2.bind(80)3.listen()80Listenqueue客戶connect()Requestfrom(IP,port)connect函數(shù)完成的功能:注冊(cè)服務(wù)器地址與遠(yuǎn)地服務(wù)器建立連接通過connect成功建立連接:服務(wù)器存在路徑可達(dá)返回值分析阻塞套接字:返回值表示連接是否成功;非阻塞套接字:返回SOCKET_ERROR,且錯(cuò)誤號(hào)為WSAEWOULDBLOCK時(shí),表示連接不能立即完成。2023/2/324關(guān)于connect函數(shù)的幾點(diǎn)說明Connect函數(shù)常見的若干錯(cuò)誤ETIMEDOUT錯(cuò)誤:若TCP客戶重發(fā)幾次SYN請(qǐng)求后仍然沒有收到SYN分節(jié)的響應(yīng)。ECONNREFUSED錯(cuò)誤:若服務(wù)器對(duì)客戶的SYN響應(yīng)是RST,表示該服務(wù)器主機(jī)在客戶端指定的端口上沒有進(jìn)程提供服務(wù)。EHOSTUNREACH錯(cuò)誤或ENETUNREACH錯(cuò)誤:客戶端發(fā)出SYN后收到ICMP目的不可達(dá)報(bào)文,在重試若干次后無效。注意:若connect失敗,則套接口不再可用,必須關(guān)閉,再次調(diào)用connect函數(shù)是無效的。2023/2/325關(guān)于connect函數(shù)的幾點(diǎn)說明2023/2/326服務(wù)器忙操作系統(tǒng)Web服務(wù)器80Listen隊(duì)列客戶1客戶3客戶2客戶請(qǐng)求在listen隊(duì)列中獲取先進(jìn)先出服務(wù)(排隊(duì))函數(shù)定義:SOCKETaccept(SOCKETs,structsockaddrFAR*addr,intFAR*addrlen)輸入?yún)?shù):s:本地套接字標(biāo)識(shí)addr:存放客戶進(jìn)程的地址和端口號(hào)addrlen:指明addr的長(zhǎng)度返回值:用于與當(dāng)前客戶進(jìn)程通信的新套接字的標(biāo)識(shí),這個(gè)套接字與原有套接字的特性相同。功能:服務(wù)器端調(diào)用該函數(shù)接收客戶進(jìn)程的連接。說明:必須在listen之后調(diào)用。2023/2/327⑤服務(wù)器端建立套接字連接——accept()2023/2/328accept()調(diào)用操作系統(tǒng)Web服務(wù)器80Listen隊(duì)列客戶1客戶3客戶2客戶請(qǐng)求在listen隊(duì)列中奪取先進(jìn)先出服務(wù)accept()已連接的socket阻塞套接字當(dāng)連接隊(duì)列上沒有等待的連接,accept進(jìn)入阻塞狀態(tài)非阻塞套接字當(dāng)連接隊(duì)列上沒有等待的連接,accept返回錯(cuò)誤WSAEWOULDBLOCK2023/2/329accept()函數(shù)的執(zhí)行情況函數(shù)定義:intsend(SOCKETs,constcharFAR*buf,intlen,intflags)輸入?yún)?shù):s:套接字標(biāo)識(shí)buf:存放發(fā)送數(shù)據(jù)的緩沖區(qū)len:發(fā)送數(shù)據(jù)的字節(jié)總數(shù)flags:對(duì)發(fā)送數(shù)據(jù)的處理方式MSG_DONTROUTE:不要路由;MSG_OOB:帶外數(shù)據(jù)返回值:成功:發(fā)送的字節(jié)總數(shù)失?。篠OCKET_ERROR2023/2/330⑥發(fā)送數(shù)據(jù)——send()使用場(chǎng)合流式套接字已建立連接的數(shù)據(jù)報(bào)套接字發(fā)送長(zhǎng)度<套接字允許的最大長(zhǎng)度相關(guān)錯(cuò)誤:如果數(shù)據(jù)太長(zhǎng)無法自動(dòng)通過下層協(xié)議,則返回WSAEMSGSIZE錯(cuò)誤,數(shù)據(jù)不會(huì)被發(fā)送。問題1:發(fā)送成功是否意味著數(shù)據(jù)傳送到達(dá)?否2023/2/331關(guān)于send函數(shù)的幾點(diǎn)說明問題2:在SOCKE_STREAM中,send函數(shù)如何獲知數(shù)據(jù)的目的主機(jī)地址?Server:accept函數(shù)獲得對(duì)方地址Client:connect函數(shù)注冊(cè)對(duì)方地址問題3:如果傳送數(shù)據(jù)的緩存區(qū)空間不夠保存需傳送的數(shù)據(jù),如何處理?阻塞模式:等待非阻塞模式:實(shí)際寫的數(shù)據(jù)可能在1到所需大小之間,其值取決于本地和遠(yuǎn)端主機(jī)的緩沖區(qū)大小。通過異步處理確定何時(shí)能夠進(jìn)一步發(fā)送數(shù)據(jù)2023/2/332關(guān)于send函數(shù)的幾點(diǎn)說明問題4:根據(jù)數(shù)據(jù)長(zhǎng)度、網(wǎng)絡(luò)允許最大長(zhǎng)度和系統(tǒng)緩存的情況,實(shí)際返回的發(fā)送長(zhǎng)度有哪些情況?設(shè)待發(fā)送的數(shù)據(jù)長(zhǎng)度為X,實(shí)際發(fā)送的字節(jié)總數(shù)為X’,分以下幾種情況討論:1)X>iMaxDg:error2)Sysbufsize<X<iMaxUdpDg:阻塞模式:等待,成功發(fā)送后X’=X非阻塞模式:X’=min{本地系統(tǒng)緩存大小,遠(yuǎn)端系統(tǒng)緩存大小}3)X<sysbuf:X’=X2023/2/333關(guān)于send函數(shù)的幾點(diǎn)說明函數(shù)定義:intrecv(SOCKETs,charFAR*buf,intlen,intflags)輸入?yún)?shù):s:套接字標(biāo)識(shí)buf:接收數(shù)據(jù)的緩沖區(qū)len:指明buf的字節(jié)數(shù)flags:指定處理數(shù)據(jù)的方式;MSG_OOB:處理帶外數(shù)據(jù);MSG_PEEK:保留數(shù)據(jù)返回值:成功:接收的字節(jié)總數(shù)失?。篠OCKET_ERROR2023/2/334⑦接收數(shù)據(jù)——recv()使用場(chǎng)合面向連接:調(diào)用前必須先建立連接無連接:調(diào)用前套接字必須綁定問題1:在流式套接字中,recv如何獲知數(shù)據(jù)來源?Server:accept函數(shù)獲得對(duì)方地址Client:connect函數(shù)注冊(cè)對(duì)方地址問題2:要接收的數(shù)據(jù)超過緩沖區(qū)大小,如何處理?最多不超過緩沖區(qū)的大??;SOCK_DGRAM:超出的那部分?jǐn)?shù)據(jù)會(huì)丟失;SOCK_STREAM:通過循環(huán)調(diào)用recv,接收到所有數(shù)據(jù);2023/2/335關(guān)于recv函數(shù)的幾點(diǎn)說明函數(shù)定義:intclosesocket(SOCKETs)輸入?yún)?shù):s:套接字標(biāo)識(shí)返回值:成功:0失?。篠OCKET_ERROR功能:關(guān)閉套接字,釋放分配給該套接字的資源;2023/2/336⑧關(guān)閉套接字——closesocket()功能:禁止某些操作函數(shù)定義:intshutdown(SOCKETs,inthow)輸入?yún)?shù):s:套接字標(biāo)識(shí)how:描述禁止哪些操作(SD_RECEIVE,SD_SEND,SD_BOTH)返回值:成功:0失?。篠OCKET_ERROR說明:本函數(shù)并不關(guān)閉套接字,且套接字所占有的資源將被一直保持到closesocket()調(diào)用。2023/2/337⑨中斷連接——shutdown()Outline2023/2/338TCP:傳輸控制協(xié)議流式套接字編程模型基本函數(shù)程序舉例功能:客戶端:與服務(wù)器建立TCP連接,讀取服務(wù)器送回的當(dāng)前時(shí)間和日期。服務(wù)器端:監(jiān)聽端口,接受客戶端請(qǐng)求,獲取本機(jī)時(shí)間并返回。程序示例:2023/2/339時(shí)間服務(wù)器舉例執(zhí)行步驟引用頭文件處理命令行參數(shù)創(chuàng)建TCP套接字指定服務(wù)器IP地址和端口與服務(wù)器建立連接接收并輸出服務(wù)器應(yīng)答關(guān)閉套接字,終止程序2023/2/340客戶端2023/2/341#include"stdafx.h"#defineMAXLINE4096 /*maxtextlinelength*/#include"Winsock2.h"#include"stdio.h“#pragmacomment(lib,"ws2_32.lib")intmain(intargc,char*argv[]){ int sockfd,n; char recvline[MAXLINE+1];

structsockaddr_in servaddr; if(argc!=2) { printf("usage:<IPaddress>"); return0; }

StartUp();

//初始化socket

//創(chuàng)建socket if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0) { printf("socketerror"); CleanUp(); return0; }2023/2/342

memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_port=htons(13); /*daytimeserver*/

servaddr.sin_addr.s_addr=inet_addr(argv[1]); //請(qǐng)求與服務(wù)器建立連接

if(connect(sockfd,(LPSOCKADDR)&servaddr, sizeof(servaddr))<0) { printf("connecterror"); CleanUp(); return0;

} //接收服務(wù)器應(yīng)答 while((n=recv(sockfd,recvline,MAXLINE,0))>0)

{ recvline[n]=0; /*nullterminate*/ if(fputs(recvline,stdout)==EOF) printf("fputserror"); } if(n<0)

printf("recverror"); closesocket(sockfd);

CleanUp(); //終止socket的使用

return0;}2023/2/343voidStartUp(){ WORDwVersionRequested;

WSADATAwsaData; wVersionRequested=MAKEWORD(2,2); WSAStartup(wVersionRequested,&wsaData);}voidCleanUp(){ WSACleanup();}執(zhí)行步驟引用頭文件創(chuàng)建TCP套結(jié)字捆綁服務(wù)器的知名端口到套接字把套接字變換成監(jiān)聽套接字接收客戶連接,獲取本地時(shí)間,發(fā)送應(yīng)答終止連接關(guān)閉套接字,終止程序2023/2/344服務(wù)器端2023/2/345#include"stdafx.h"#include<time.h>#include"Winsock2.h"#include"stdio.h“#pragmacomment(lib,"ws2_32.lib")#defineMAXLINE4096 /*maxtextlinelength*/#defineLISTENQ1024 /*2ndargumenttolisten()*/intmain(intargc,char*argv[]){ int listenfd,co

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論