多線程網(wǎng)絡(luò)編程課件_第1頁
多線程網(wǎng)絡(luò)編程課件_第2頁
多線程網(wǎng)絡(luò)編程課件_第3頁
多線程網(wǎng)絡(luò)編程課件_第4頁
多線程網(wǎng)絡(luò)編程課件_第5頁
已閱讀5頁,還剩46頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

多線程網(wǎng)絡(luò)編程R&DIP夏建嵬2007/0810/13/20221AsiaInfoTechnologies(China),Ltd.課程目標理解應(yīng)用系統(tǒng)日志機制,熟練使用日志接口掌握socket編程基礎(chǔ),能理解socket封裝類掌握posix多線程編程基礎(chǔ)能輕松快速構(gòu)建穩(wěn)定的、可擴展的多線程服務(wù)器10/13/20222AsiaInfoTechnologies(China),Ltd.課程內(nèi)容應(yīng)用系統(tǒng)的日志機制介紹深入Posix編程深入Socket編程構(gòu)建多線程網(wǎng)絡(luò)服務(wù)器10/13/20223AsiaInfoTechnologies(China),Ltd.Socket編程TCP/IP協(xié)議概述TCP編程UDP編程10/13/20224AsiaInfoTechnologies(China),Ltd.TCP/IP協(xié)議概述-協(xié)議分層10/13/20225AsiaInfoTechnologies(China),Ltd.TCP/IP協(xié)議概述-主機間的連接10/13/20226AsiaInfoTechnologies(China),Ltd.TCP/IP協(xié)議概述-基本概念字節(jié)順序:機器結(jié)構(gòu)或網(wǎng)絡(luò)硬件的差異小端(Little-Endian):最低存儲地址包含了整數(shù)的最低位置。大端(Big-Endian):最低存儲地址包含了整數(shù)的最高位置。網(wǎng)絡(luò)標準字節(jié)順序:首先發(fā)送整數(shù)中的最高有效字節(jié)(大端方式)問題:字符數(shù)組需要進行轉(zhuǎn)換嗎?IP地址的分類10/13/20227AsiaInfoTechnologies(China),Ltd.網(wǎng)絡(luò)掩碼

為了更充分地利用寶貴的IP地址資源,子網(wǎng)的概念被引入。為此,IP地址的主機部分又被分為子網(wǎng)部分和主機部分。IP地址=網(wǎng)絡(luò)地址+子網(wǎng)地址+主機地址網(wǎng)絡(luò)掩碼(32位):某位為1,代表IP地址中的對應(yīng)位為網(wǎng)絡(luò)地址;某位為0,代表IP地址中的對應(yīng)位為主機地址。路由器在處理子網(wǎng)的IP數(shù)據(jù)包時,將數(shù)據(jù)包的目標地址和各個子網(wǎng)的網(wǎng)絡(luò)掩碼進行“與”操作,然后將結(jié)果與子網(wǎng)的地址進行比較。TCP/IP協(xié)議概述-基本概念10/13/20228AsiaInfoTechnologies(China),Ltd.TCP/IP協(xié)議概述-基本概念不同體系結(jié)構(gòu)的編程模型ILP32模型:32位系統(tǒng)上使用,意即Integer-Long-Pointer都是32位。LP64模型:64位系統(tǒng)上使用,意即Long-Pointer都是64位。端口號

TCP/UDP協(xié)議使用16位的端口號來區(qū)分不同的進程。RFC1700包含了由IANA定義的端口列表:知名(well-known)端口:0~1023,由IANA分配和控制。已注冊(register)端口:1024~49151,在IANA注冊但不受其控制。動態(tài)(dynamic)端口:49152~65535,臨時端口,可隨意使用。10/13/20229AsiaInfoTechnologies(China),Ltd.TCP/IP協(xié)議概述-IP協(xié)議IP協(xié)議概述

IP(InternetProtocol)協(xié)議是網(wǎng)絡(luò)層協(xié)議,主要功能及特點:不可靠的數(shù)據(jù)報傳輸服務(wù)。路由選擇功能。無連接服務(wù)。最大努力傳送(best-effortdelivery)特性。IP報文的格式10/13/202210AsiaInfoTechnologies(China),Ltd.TCP/IP協(xié)議概述-套接字地址結(jié)構(gòu)通用套接字地址結(jié)構(gòu)struct

sockaddr{ unsignedshortsa_family; //地址類型,AF_INET charsa_data[14]; //協(xié)議地址};TCP/IP協(xié)議相關(guān)的地址結(jié)構(gòu)//IP地址結(jié)構(gòu)struct

in_addr{ __u32s_addr; //IP地址,網(wǎng)絡(luò)字節(jié)順序};//TCP/IP協(xié)議的套接字地址struct

sockaddr_in{ shortinsa_family; //地址類型,為AF_INET unsignedshortint

sin_port; //端口號,網(wǎng)絡(luò)字節(jié)順序

struct

in_addr

sin_addr; //IP地址

//填充字節(jié),最好初始化為0};10/13/202211AsiaInfoTechnologies(China),Ltd.TCP/IP協(xié)議概述-基礎(chǔ)socket函數(shù)介紹字節(jié)轉(zhuǎn)換相關(guān)函數(shù)//h:hostn:networkl:longs:shortuint32_thtonl(uint32_thostlong);uint16_thtons(uint16_thostshort);uint32_tntohl(uint32_tnetlong);uint16_tntohs(uint16_tnetshort);地址轉(zhuǎn)換相關(guān)函數(shù)//a:asciin:networkint

inet_aton(constchar*cp,struct

in_addr*inp);char*inet_ntoa(struct

in_addrin);in_addr_t

inet_addr(constchar*cp);in_addr_t

inet_network(constchar*cp);10/13/202212AsiaInfoTechnologies(China),Ltd.gethostbyname函數(shù)//首先查本地hosts文件,然后查DNSstruct

hostent*gethostbyname(constchar*name);int

gethostbyname_r(constchar*name,struct

hostent*ret,char*buf,size_t

buflen,

struct

hostent**result,int*h_errnop);//hostent結(jié)構(gòu)struct

hostent{ char*h_name; //正式的主機名

char**h_aliases; //別名列表

int

h_addrtype; //地址類型

int

h_length; //地址長度

char**h_addr_list; //IP地址列表

}#defineh_addrh_addr_list[0]TCP/IP協(xié)議概述-基礎(chǔ)socket函數(shù)介紹//gethostbyname_r使用實例struct

hostent*result;struct

hostent

hentry;charhdata[4096];int

hlen=sizeof(hdata);int

herr=0;memset(hdata,0,sizeof(hdata));intret;ret=gethostbyname_r(m_cnAddr.c_str(),&hentry,hdata,hlen,&result,&herr);if(0!=ret){ //錯誤處理并返回}memcpy(&ipaddr,hentry.h_addr_list[0],hentry.h_length);10/13/202213AsiaInfoTechnologies(China),Ltd.gethostbyaddr函數(shù)struct

hostent*gethostbyaddr(constchar*addr,int

len,intfamily);struct

hostent*gethostbyaddr_r(constchar*addr,intlength,inttype,struct

hostent*result,char*buffer,int

buflen,int*h_errnop);注:1、addr參數(shù)是指向in_addr類型的指針。

2、Linux沒有提供gethostbyaddr_r(),上面的API是Solaris提供的。獲得或設(shè)置套接字選項int

getsockopt(ints,intlevel,int

optname,void*optval,socklen_t*optlen);int

setsockopt(ints,intlevel,int

optname,constvoid*optval,socklen_t

optlen);

選項的層次SOL_SOCKET :通用套接字選項。IPPROTO_IP :IP選項。IPPROTO_TCP :TCP選項。TCP/IP協(xié)議概述-基礎(chǔ)socket函數(shù)介紹10/13/202214AsiaInfoTechnologies(China),Ltd.常用選項說明SO_ERROR選項

獲得并清除套接字錯誤。例如:

int

sock_err=0;

int

sock_err_len=sizeof(sock_err);//注意:別忘了

int

sockopt_ret=getsockopt(socketFD(),SOL_SOCKET,SO_ERROR, (void*)&sock_err,(socklen_t*)&sock_err_len);SO_LINGER選項延遲關(guān)閉選項,用于指定close()函數(shù)對面向連接的協(xié)議如何操作。默認情下,close()函數(shù)調(diào)用后會立即返回,讓TCP協(xié)議處理發(fā)送緩沖區(qū)中的剩余數(shù)據(jù)和連接關(guān)閉操作。LINGER選項結(jié)構(gòu)為:structlinger{

int

l_onoff; //允許/禁止延遲操作,默認為0(禁止)

int

l_linger; //延遲時間(秒)};TCP/IP協(xié)議概述-基礎(chǔ)socket函數(shù)介紹10/13/202215AsiaInfoTechnologies(China),Ltd.LINGER結(jié)構(gòu)說明:l_onoff為0禁止close()延遲操作,l_linger成員被忽略。close()按默認方式工作。l_onoff非0,l_linger為0調(diào)用close()后夭折該連接,即丟棄發(fā)送緩沖區(qū)中的未發(fā)送數(shù)據(jù),并向?qū)Χ税l(fā)送RST報文之后關(guān)閉連接,這樣可以避免TIME_WAIT狀態(tài)。但會造成數(shù)據(jù)丟失/數(shù)據(jù)混亂/連接非正常關(guān)閉。l_onoff非0,l_linger非0調(diào)用close()后,其返回將會延遲l_linger指定的秒數(shù)。SO_RCVBUF和SO_SNDBUF選項SO_RCVBUF選項用于設(shè)置套接字接收緩沖區(qū)大小,而SO_SNDBUF選項用于設(shè)置套接字發(fā)送緩沖區(qū)大小。加大緩沖區(qū)大小可以改善網(wǎng)絡(luò)處理性能,但緩沖區(qū)大小都有個上限限制。注意:對于TCP連接而言,修改緩沖區(qū)大小必須在連接建立之前,即connect()或listen()前對于UDP連接而言,沒有實際的發(fā)送緩沖區(qū),該選項表示能夠發(fā)送的、最大UDP報文的大小。TCP/IP協(xié)議概述-基礎(chǔ)socket函數(shù)介紹10/13/202216AsiaInfoTechnologies(China),Ltd.SO_REUSEADDR選項該選項用于解決重復(fù)綁定問題,后面詳細介紹。需要注意的是:該選項必須在綁定操作之前設(shè)置。例如://settheSO_REUSEADDRoption,sockfd為打開的socket描述符int

optval=1;if(0!=setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval))){//錯誤處理}……if(0!=bind(sockfd,…){}多路監(jiān)聽函數(shù)select()函數(shù)select()可用于同時檢測多個描述符是否就緒。當某個描述符就緒時,函數(shù)select()成功返回,否則,它將阻塞直到超時(如果設(shè)置)。TCP/IP協(xié)議概述-基礎(chǔ)socket函數(shù)介紹10/13/202217AsiaInfoTechnologies(China),L

select(intn,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,struct

timeval*timeout);該函數(shù)能同時檢測三個描述符集合:讀集合(readfds),寫集合(writefds)和異常集合(exceptfds)。讀就緒的條件接收緩沖區(qū)的數(shù)據(jù)量不小于套接字的接收下限。連接的讀通道被關(guān)閉,即收到FIN報文。監(jiān)聽套接字的完成隊列不為空,即表示有已經(jīng)建立的連接。調(diào)用函數(shù)connect()以非阻塞方式進行連接的過程中出現(xiàn)錯誤。寫就緒的條件發(fā)送緩沖區(qū)的可用空間不小于套接字的發(fā)送下限。連接的寫通道被關(guān)閉。注:向已經(jīng)關(guān)閉寫通道的連接上寫數(shù)據(jù)會產(chǎn)生SIGPIPE信號。非阻塞式套接字的TCP連接建立成功。調(diào)用函數(shù)connect()以非阻塞方式進行連接過程中出現(xiàn)錯誤。異常就緒的條件套接字上有帶外數(shù)據(jù)未接收。套接字仍在帶外標記的范圍內(nèi),即帶外數(shù)據(jù)還在正常的字節(jié)流中未被讀取。TCP/IP協(xié)議概述-基礎(chǔ)socket函數(shù)介紹10/13/202218AsiaInfoTechnologies(China),Ltd.描述符集合相關(guān)的宏:FD_CLR(int

fd,fd_set*set); //將某個描述符從指定的描述符集中刪除FD_ISSET(int

fd,fd_set*set); //檢查某個描述符是否被設(shè)置(就緒)FD_SET(int

fd,fd_set*set); //將某個描述符加入到指定的描述符集中FD_ZERO(fd_set*set); //清空整個描述符集

使用函數(shù)select():

fd_set

wset;

FD_ZERO(&wset);

FD_SET(the_sock_fd,&wset); while(沒有讀完){ //重新計算超時時間rel

intret=select(the_sock_fd+1,NULL,&wset,NULL,&rel); if(0!=ret){ //錯誤處理

} //讀剩余字節(jié)數(shù)

}TCP/IP協(xié)議概述-基礎(chǔ)socket函數(shù)介紹10/13/202219AsiaInfoTechnologies(China),Ltd.Socket編程TCP/IP協(xié)議概述TCP編程UDP編程10/13/202220AsiaInfoTechnologies(China),Ltd.TCP編程-協(xié)議概述TCP協(xié)議概述

TCP(TransmissionControlProtocol)協(xié)議,是基于IP協(xié)議的傳輸控制協(xié)議,提供可靠的、面向連接的服務(wù)。主要特征:可靠性:通過確認和超時重傳來保證的。面向無結(jié)構(gòu)的字節(jié)流:數(shù)據(jù)之間沒有界限。面向連接:通信之前,必須建立連接;通信結(jié)束,必須關(guān)閉連接。全雙工:通信雙方都可以同時發(fā)送和接收數(shù)據(jù)。提供流量控制機制:通過滑動窗口實現(xiàn)。TCP報文的格式10/13/202221AsiaInfoTechnologies(China),Ltd.TCP編程-建立連接建議TCP連接

TCP協(xié)議采用三次握手方式來建立一條可靠的連接。在這個過程中,連接雙方完成各自初始序列號的交換。10/13/202222AsiaInfoTechnologies(China),Ltd.TCP編程-關(guān)閉連接關(guān)閉TCP連接由于TCP連接是全雙工連接,因此,需要同時關(guān)閉讀通道和寫通道。10/13/202223AsiaInfoTechnologies(China),Ltd.TCP編程-基本函數(shù)介紹函數(shù)socket()int

socket(intdomain,inttype,intprotocol);【參數(shù)說明】domain [in]協(xié)議簇,TCP/IP為AF_INET。type [in]套接字類型。TCP:SOCK_STREM;UDP:SOCK_DGRAM。protocol [in]使用的協(xié)議,默認為0。對于TCP/UDP而言,設(shè)為0即可?!竟δ堋吭摵瘮?shù)在內(nèi)核中創(chuàng)建一個套接字結(jié)構(gòu),并返回一個標識該結(jié)構(gòu)的描述符。連接相關(guān)的所有信息都保存在該套接字結(jié)構(gòu)中。函數(shù)bind()int

bind(int

sockfd,struct

sockaddr*my_addr,socklen_t

addrlen);【功能】該函數(shù)將套接字綁定在到本地地址和端口。10/13/202224AsiaInfoTechnologies(China),Ltd.TCP編程-基本函數(shù)介紹【說明】對于服務(wù)端程序而言,bind()函數(shù)必須被調(diào)用,以綁定自己的公認端口號,而IP地址可以設(shè)定為通用地址INADDR_ANY或某個本地IP地址。對于客戶端程序而言,一般不需要指定套接字地址(本地IP地址和端口),因為系統(tǒng)會自動為套接字選擇一個未用的端口和本地IP地址,因此,沒必要調(diào)用bind()函數(shù):IP地址可以指定設(shè)為某個本地IP地址或INADDR_ANY。端口可以設(shè)為非零值或0,其中,0表示由系統(tǒng)指定端口號。建議:一般情況下,客戶端程序請盡量不要使用固定端口。(為什么?)函數(shù)listen()intlisten(intsockfd,intbacklog);【功能】將一個套接字轉(zhuǎn)換為監(jiān)聽套接字(listeningsocket),TCP狀態(tài)也由CLOSED轉(zhuǎn)換為LISTEN狀態(tài)。其中,backlog設(shè)置請求隊列的最大長度。10/13/202225AsiaInfoTechnologies(China),Ltd.TCP編程-基本函數(shù)介紹【說明】每個監(jiān)聽套接字都會維護兩個隊列:未完成連接隊列和已完成連接隊列。未完成連接包含那些“沒有完成三次握手”的連接,而已完成連接隊列則包含那些“已完成三次握手,但未被accept”的連接。函數(shù)accept()int

accept(ints,struct

sockaddr*addr,socklen_t*addrlen);【功能】從監(jiān)聽套接字的完成連接隊列中接收一個連接。如果沒有已經(jīng)建立的連接,該函數(shù)會被阻塞。10/13/202226AsiaInfoTechnologies(China),Ltd.TCP編程-基本函數(shù)介紹函數(shù)connect()int

connect(int

sockfd,conststruct

sockaddr*serv_addr,socklen_t

addrlen);【功能】客戶端調(diào)用該函數(shù)發(fā)起三次握手過程,和服務(wù)端建立連接。【例子】struct

sockaddr_in

addrin;memset(&addrin,0,sizeof(addrin);addrin.sin_family=AF_INET; addrin.sin_port=8080; //服務(wù)端監(jiān)聽端口addrin.sin_addr.s_addr=inet_addr(“5”); //服務(wù)端地址if(0!=connect(sockfd,(struct

sockaddr*)&addrin,sizeof(addrin))){//連接失敗,錯誤處理}10/13/202227AsiaInfoTechnologies(China),Ltd.TCP編程-基本函數(shù)介紹函數(shù)read()/write()ssize_t

read(int

sockfd,void*buf,size_tcount);ssize_t

write(int

fd,constvoid*buf,size_tcount);【功能】函數(shù)read()將套接字接收緩沖區(qū)(內(nèi)核)中的數(shù)據(jù)拷貝到用戶緩沖區(qū),真正的網(wǎng)絡(luò)數(shù)據(jù)的接收操作是由內(nèi)核完成的。函數(shù)write()負責將發(fā)送數(shù)據(jù)拷貝到套接字發(fā)送緩沖區(qū)(并不表示數(shù)據(jù)已經(jīng)發(fā)送到對方了)?!菊f明】關(guān)于函數(shù)read()的返回值:=0 :收到FIN,對端關(guān)閉了連接。>0 :有數(shù)據(jù)到達,返回值為收到的字節(jié)數(shù)。<0 :如果errno是EINTR,表明是被信號中斷的,不影響后續(xù)的讀操作;如果是其它錯誤,需要進行處理。關(guān)于函數(shù)write()的返回值:<0 :如果errno是EINTR,表明是被信號中斷的,不影響后續(xù)的寫操作;其它錯誤,需要進行處理。>0 :拷貝的字節(jié)數(shù),說明發(fā)送緩沖區(qū)還有空間。=0:很奇怪,一般當作錯誤處理。(???)高效的讀/寫操作方法:多路監(jiān)聽select()+阻塞式的讀/寫。10/13/202228AsiaInfoTechnologies(China),Ltd.TCP編程-基本函數(shù)介紹函數(shù)close()

int

close(int

fd);【功能】關(guān)閉套接字描述符。選項SO_LINGER可以控制close()的關(guān)閉操作。函數(shù)shutdown()int

shutdown(intsocket,inthow);【功能】關(guān)閉TCP連接。其中how指定了關(guān)閉方式:=0 :關(guān)閉讀通道,之后的所有讀操作都將返回0。在調(diào)用shutdown()時,如果套接字接收緩沖區(qū)還有數(shù)據(jù),它們將會被丟棄;讀通道被關(guān)閉之后,TCP協(xié)議會對對端發(fā)送的所有數(shù)據(jù)返回確認,但數(shù)據(jù)會被丟棄。=1 :關(guān)閉寫通道,之后所有的寫操作都將產(chǎn)生SIGPIPE信號(注意處理,如果忽略該信號,函數(shù)會返回EPIPE)。在關(guān)閉寫通道時,套接字發(fā)送緩沖區(qū)中所有沒有發(fā)送的數(shù)據(jù)將會被發(fā)送,然后發(fā)送FIN。=2 :關(guān)閉讀通道和寫通道。【說明】shutdown()和close()區(qū)別:前者針對TCP連接,而后者是針對的套接字描述符。10/13/202229AsiaInfoTechnologies(China),Ltd.TCP編程-簡單事務(wù)處理利用shutdown()函數(shù)可以實現(xiàn)簡單的事務(wù)處理(transaction)。這里所說的事務(wù)指的是一次簡單的報文交換過程:請求發(fā)給服務(wù)器,然后服務(wù)器返回應(yīng)答給客戶端。10/13/202230AsiaInfoTechnologies(China),Ltd.TCP編程-地址重復(fù)綁定的問題案例:快速重啟服務(wù)器失敗

描述:監(jiān)聽服務(wù)器已經(jīng)關(guān)閉,但該服務(wù)器接收的連接還未完全關(guān)閉(通信當中或TIME_WAIT狀態(tài)),這時重啟服務(wù)器會報如下錯誤:Addressalreadyinuse(EADDRINUSE)原因:監(jiān)聽套接字和accepted的套接字共享同樣的本地地址和端口,因此,重啟后試圖綁定活動連接的端口是不允許的。解決方案:在綁定操作之前設(shè)置SO_REUSEADDR選項。10/13/202231AsiaInfoTechnologies(China),Ltd.TCP編程-客戶端和服務(wù)端總結(jié)10/13/202232AsiaInfoTechnologies(China),Ltd.TCP編程-非阻塞式的主動連接初始化套接字

。更改套接字為非阻塞方式。fcntl(sockfd,F_GETFL,0); //獲得描述符標志fcntl(sockfd,F_SETFL,flags); //設(shè)置描述符標志調(diào)用connect()連接TCP服務(wù)器。正常情況下,函數(shù)connect()會立即返回,不會等待三次握手完成。這時,connect()會返回-1,且errno為EINPROGRESS或EWOULDBLOCK。調(diào)用select()函數(shù)監(jiān)聽該套接字的讀操作或?qū)懖僮魇欠窬途w。如果select()出錯或超時,表明連接失敗。通過SO_ERROR選項,獲得套接字錯誤。如果套接字發(fā)生錯誤,表明連接不成功。恢復(fù)套接字的原始標志。10/13/202233AsiaInfoTechnologies(China),Ltd.TCP編程-讀寫操作對于TCP套接字,一般采取如下方式:多路監(jiān)聽select()+阻塞式讀/寫。這樣,我們既可以充分利用阻塞式高效的特點,又可以通過select()來嚴格控制讀/寫操作的超時。函數(shù)CSocket::selectSocket()intCSocket::selectSocket(my_uint32_t&result,my_uint32_ttimeout);【參數(shù)說明】result [in/out]想要監(jiān)聽的類型/就緒的類型。類型可以是:可讀/可寫/異常就緒timeout [in]監(jiān)聽超時時間?!竟δ堋繉Socket對應(yīng)的套接字進行監(jiān)聽(可讀/可寫/異常就緒),監(jiān)聽的結(jié)果也保存在參數(shù)result中?!痉祷刂怠? :監(jiān)聽成功,可讀、可寫或異常就緒。0 :監(jiān)聽超時。-1 :監(jiān)聽出錯。10/13/202234AsiaInfoTechnologies(China),Ltd.TCP編程-讀寫操作函數(shù)CTCPPeer::readSocket()CTCPPeer::readSocket(char*buf,int

len,int&rbytes);【參數(shù)說明】buf [in]數(shù)據(jù)緩沖區(qū)指針。len [in]緩沖區(qū)長度。rbytes [in/out]要讀的字節(jié)數(shù)/實際讀取的字節(jié)數(shù)?!竟δ堋吭谥付ǖ臅r間內(nèi)讀取指定長度的數(shù)據(jù)到緩沖區(qū),超時時間在初始化CTCPPeer對象時設(shè)置?!痉祷刂怠? :讀數(shù)據(jù)成功。0 :對端關(guān)閉了連接,rbytes保存已讀的字節(jié)數(shù)。<0 :讀數(shù)據(jù)失敗,如果超時,返回ERR_SELTIMEOUT(-1986)?!居懻摗?、如果返回ERR_SELTIMEOUT,且返回的rbytes不為0,該如何處理?如果rbytes為0,又該如何處理?10/13/202235AsiaInfoTechnologies(China),Ltd.TCP編程-讀寫操作函數(shù)CTCPPeer::writeSocket()CTCPPeer::readSocket(char*buf,int

len,int&wbytes);【參數(shù)說明】buf [in]數(shù)據(jù)緩沖區(qū)指針。len [in]緩沖區(qū)長度。wbytes [in/out]要發(fā)送的字節(jié)數(shù)/實際發(fā)送的字節(jié)數(shù)?!竟δ堋吭谥付ǖ臅r間內(nèi)發(fā)送指定長度的數(shù)據(jù),超時時間在初始化CTCPPeer對象時設(shè)置。【返回值】1 :發(fā)送數(shù)據(jù)成功。0 :對端關(guān)閉了連接,wbytes保存已發(fā)送的字節(jié)數(shù)。<0 :發(fā)送數(shù)據(jù)失敗,如果超時,返回ERR_SELTIMEOUT(-1986)。【討論】1、如果返回ERR_SELTIMEOUT,且返回的wbytes不為0,該如何處理?如果wbytes為0,又該如何處理?10/13/202236AsiaInfoTechnologies(China),Ltd.TCP編程-例子查錯//頭文件略去int

myServer(){

struct

sockaddr_in

addr;

int

addr_len; charbuf[102400];

int

sockfd;

int

fd=socket(PF_INET,SOCK_DGRAM,0);

if(fd<0)return-1;

addr.sin_family=AF_INET;

addr.sin_port=1000;

addr.sin_addr.s_addr=INADDR_ANY;

if(bind(fd,(struct

sockaddr*)&addr,sizeof(addr)==-1)return-1;

if(sockfd=accept(fd,(struct

sockaddr*)&addr,&addrlen)==-1)return-1;

intn;

while((n=read(fd,buf,sizeof(buf))>0)write(sockfd,buf,n);

close(fd); return0;}10/13/202237AsiaInfoTechnologies(China),Ltd.TCP編程-角色劃分在TCP編程中,涉及到三種角色:被動連接角色、主動連接角色和通信角色。被動連接角色指的是監(jiān)聽服務(wù)端(TCPServer),主動連接角色指的是客戶端(TCPClient),而通信角色則是由前兩者生成的、用于數(shù)據(jù)傳輸?shù)倪B接,我們常稱之為對等實體(TCPPeer)。10/13/202238AsiaInfoTechnologies(China),Ltd.TCP編程-TCP類的組織10/13/202239AsiaInfoTechnologies(China),Ltd.TCP編程-TCP常連接池在實時性要求較高的應(yīng)用中,為了節(jié)省建立TCP花費的時間,經(jīng)常采用TCP常連接池。常連接池中的所有連接都是在啟動之初建立的,需要的時候從池中取一條連接,用完后放回池中。初始化清除例程無效連接檢查和修復(fù)例程取連接放回連接10/13/202240AsiaInfoTechnologies(China),Ltd.TCP編程-問題解答問題解答10/13/202241AsiaInfoTechnologies(China),Ltd.Socket編程TCP/IP協(xié)議概述TCP編程UDP編程10/13/202242AsiaInfoTechnologies(China),Ltd.UDP編程-協(xié)議概述UDP協(xié)議特征不可靠性:數(shù)據(jù)報文可能丟失或損壞。非面向連接:客戶端和服務(wù)端沒有固定的通道。亂序性:先發(fā)送的報文不一定會先被收到。無流控機制。面向記錄的消息:消息要么全部被收到,要么什么也收不到。響應(yīng)快:IP協(xié)議層具有盡最大努力傳送的特點,同時,沒有連接和可靠性開銷。UDP應(yīng)用需要自己處理報文的丟失、亂序等問題。UDP報文的格式10/13/202243AsiaInfoTechnologies(China),Ltd.UDP編程-協(xié)議概述UDP協(xié)議應(yīng)用場合網(wǎng)絡(luò)數(shù)據(jù)多為消息,通信方式為發(fā)送-接收一次模型。擁有大量的客戶端。無數(shù)據(jù)安全性要求。網(wǎng)絡(luò)負擔重,但響應(yīng)速度要求較高,如視頻點播。10/13/202244AsiaInfoTechnologies(China),Ltd.UDP編程-重要函數(shù)介紹函數(shù)recvfrom()/sendto()ssize_t

recvfrom(ints,void*buf,size_t

len,intflags,struct

sockaddr*from,socklen_t*fromlen);ssize_t

sendto(ints,constvoid*buf,size_t

len,intflags,conststruct

sockaddr*to,socklen_t

tolen);【參數(shù)說明】s [in]套接字描述符。buf [in]發(fā)送或接收緩沖區(qū)。len [in]發(fā)送或接收消息的長度。flags [in]發(fā)送或接收標志,對UDP意義不大,可設(shè)為0。from [in]發(fā)送方地址。fromlen [in]發(fā)送方地址長度。to [in]接收方地址。tolen [in]接收方地址長度?!竟δ堋縭ecvfrom()函數(shù)接收UDP報文,從系統(tǒng)緩沖區(qū)拷貝到用戶緩沖區(qū)中。而sendto則將UDP報文從用戶緩沖區(qū)拷貝到系統(tǒng)緩沖區(qū)。10/13/202245AsiaInfoTechnologies(China),Ltd.UDP編程-重要函數(shù)介紹【說明】關(guān)于返回值recvfrom()/sendto()的返回值有以下兩種情況,注意與TCP的區(qū)別:>=0 :接收/發(fā)送的字節(jié)數(shù),0表示是空報文,是UDP協(xié)議允許的。<0 :出錯,需要進行處理。關(guān)于SO_SNDBUF選項SO_SNDBUF選項可以設(shè)置UDP發(fā)送緩沖區(qū)的大小,但對UDP而言,它指的是接被發(fā)送UDP報文的最大長度。如果發(fā)送的UDP報文大于這個值,sendto()會返回EMSGSIZE。由于UDP沒有實際的發(fā)送緩沖區(qū),因此,可以認為UDP報文的sendto()函數(shù)是幾乎不會阻塞的。

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論