版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
嵌入式LINUX網(wǎng)絡(luò)編程主要內(nèi)容
Internet與TCP/IP協(xié)議
Internet歷史
OSI模型與TCP/IP協(xié)議體系結(jié)構(gòu)
TCP/IP協(xié)議
TCP和UDP協(xié)議
TCP/IP網(wǎng)絡(luò)編程預(yù)備知識系統(tǒng)調(diào)用TCP編程/UDP編程API網(wǎng)絡(luò)封包格式和IP,TCP頭TCP握手過程I/O模型和服務(wù)器模型
網(wǎng)絡(luò)調(diào)試和協(xié)議分析—wireshark和tcpdump使用2網(wǎng)絡(luò)高級話題網(wǎng)絡(luò)屬性設(shè)置和超時(shí)檢測帶外數(shù)據(jù)及編程方法廣播和組播UNIX域套接字3Internet與TCP/IP協(xié)議Internet歷史OSI模型與TCP/IP協(xié)議體系結(jié)構(gòu)TCP/IP協(xié)議TCP和UDP協(xié)議4Internet的歷史Internet-“冷戰(zhàn)”的產(chǎn)物1957年10月和11月,前蘇聯(lián)先后有兩顆“Sputnik”衛(wèi)星上天1958年美國總統(tǒng)艾森豪威爾向美國國會(huì)提出建立DARPA(DefenseAdvancedResearchProjectAgency),即國防部高級研究計(jì)劃署,簡稱ARPA1968年6月DARPA提出“資源共享計(jì)算機(jī)網(wǎng)絡(luò)”(ResourceSharingComputerNetworks),目的在于讓DARPA的所有電腦互連起來,這個(gè)網(wǎng)絡(luò)就叫做ARPAnet,即“阿帕網(wǎng)”,是Interne的最早雛形56Linux為用戶提供了完善的、強(qiáng)大的網(wǎng)絡(luò)功能在Internet中,為了使硬件和軟件有差異的計(jì)算機(jī)之間聯(lián)網(wǎng)、彼此之間數(shù)據(jù)兼容,需要建立一種大家共同都必須遵守的標(biāo)準(zhǔn),這樣才能讓不同的電腦按照一定的規(guī)則數(shù)據(jù)交互和資源共享,這種標(biāo)準(zhǔn)就是網(wǎng)絡(luò)協(xié)議。網(wǎng)絡(luò)協(xié)議6網(wǎng)絡(luò)地址A類地址第1字節(jié)為網(wǎng)絡(luò)地址,其他3個(gè)字節(jié)為主機(jī)地址。第1字節(jié)的最高位固定為0–55B類地址第1字節(jié)和第2字節(jié)是網(wǎng)絡(luò)地址,其他2個(gè)字節(jié)是主機(jī)地址。第1字節(jié)的前兩位固定為10–55C類地址前3個(gè)字節(jié)是網(wǎng)絡(luò)地址,最后1個(gè)字節(jié)是主機(jī)地址。第1字節(jié)的前3位固定為110–55D類地址(組播地址)不分網(wǎng)絡(luò)地址和主機(jī)地址,第1字節(jié)的前4位固定為1110–557網(wǎng)絡(luò)的體系結(jié)構(gòu)網(wǎng)絡(luò)采用分而治之的方法設(shè)計(jì),將網(wǎng)絡(luò)的功能劃分為不同的模塊,以分層的形式有機(jī)組合在一起。每層實(shí)現(xiàn)不同的功能,其內(nèi)部實(shí)現(xiàn)方法對外部其他層次來說是透明的。每層向上層提供服務(wù),同時(shí)使用下層提供的服務(wù)網(wǎng)絡(luò)體系結(jié)構(gòu)即指網(wǎng)絡(luò)的層次結(jié)構(gòu)和每層所使用協(xié)議的集合兩類非常重要的體系結(jié)構(gòu):OSI與TCP/IP8OSI開放系統(tǒng)互聯(lián)模型OSI模型相關(guān)的協(xié)議已經(jīng)很少使用,但模型本身非常通用OSI模型是一個(gè)理想化的模型,由于過于復(fù)雜,在實(shí)際中得不到廣泛的使用,尚未有完整的實(shí)現(xiàn)。OSI模型共有七層(右圖)。9網(wǎng)絡(luò)互聯(lián)促成了TCP/IP協(xié)議的產(chǎn)生早期的ARPAnet使用網(wǎng)絡(luò)控制協(xié)議(NetworkControlProtocol,NCP),不同類型和不同操作系統(tǒng)的計(jì)算機(jī)不能互聯(lián),并且NCP沒有糾錯(cuò)功能。1973年由Kahn和VintonCerf兩人合作為ARPAnet開發(fā)了新的互聯(lián)協(xié)議。1974年12月兩人正式發(fā)表第一份TCP協(xié)議詳細(xì)說明,從此,TCP/IP協(xié)議誕生。1983年ARPAnet上停止使用NCP,互聯(lián)網(wǎng)上的主機(jī)全部使用TCP/IP協(xié)議。TCP/IP協(xié)議成為Internet中的“世界語”10網(wǎng)絡(luò)互聯(lián)促成了TCP/IP協(xié)議的產(chǎn)生11TCP/IP協(xié)議TCP/IP協(xié)議傳輸控制/網(wǎng)際協(xié)議(TransferControlProtocol/InternetProtocol)又稱作網(wǎng)絡(luò)通訊協(xié)議Internet國際互聯(lián)網(wǎng)絡(luò)的基礎(chǔ),RFC793TCP/IP實(shí)際上是由幾個(gè)不同的協(xié)議組成的,這些協(xié)議在不同層面上提供不同的應(yīng)用和服務(wù)。所以又稱為TCP/IP協(xié)議族。四個(gè)層次:網(wǎng)絡(luò)接口層、網(wǎng)際層、傳輸層、應(yīng)用層12TCP/IP協(xié)議族的體系結(jié)構(gòu)TCP/IP協(xié)議是Internet事實(shí)上的工業(yè)標(biāo)準(zhǔn)。一共有四層13TCP/IP與OSI參考模型的對應(yīng)關(guān)系14TCP/IP協(xié)議下的數(shù)據(jù)包EthernetheaderIPheaderTCPheaderApp.headerUserdataEthernettrailer14202046-150015數(shù)據(jù)的封裝與傳遞過程16TCP頭1717IP頭1818TCP協(xié)議特點(diǎn)TCP(即傳輸控制協(xié)議):是一種面向連接的傳輸層協(xié)議,它能提供高可靠性通信(即數(shù)據(jù)無誤、數(shù)據(jù)無丟失、數(shù)據(jù)無失序、數(shù)據(jù)無重復(fù)到達(dá)的通信)適用情況:適合于對傳輸質(zhì)量要求較高,以及傳輸大量數(shù)據(jù)的通信。在需要可靠數(shù)據(jù)傳輸?shù)膱龊?,通常使用TCP協(xié)議MSN/QQ等即時(shí)通訊軟件的用戶登錄賬戶管理相關(guān)的功能通常采用TCP協(xié)議19UDP協(xié)議的特點(diǎn)UDP(UserDatagramProtocol)用戶數(shù)據(jù)報(bào)協(xié)議,是不可靠的無連接的協(xié)議。在數(shù)據(jù)發(fā)送前,因?yàn)椴恍枰M(jìn)行連接,所以可以進(jìn)行高效率的數(shù)據(jù)傳輸。適用情況:發(fā)送小尺寸數(shù)據(jù)(如對DNS服務(wù)器進(jìn)行IP地址查詢時(shí))在接收到數(shù)據(jù),給出應(yīng)答較困難的網(wǎng)絡(luò)中使用UDP。(如:無線網(wǎng)絡(luò))適合于廣播/組播式通信中。MSN/QQ/Skype等即時(shí)通訊軟件的點(diǎn)對點(diǎn)文本通訊以及音視頻通訊通常采用UDP協(xié)議流媒體、VOD、VoIP、IPTV等網(wǎng)絡(luò)多媒體服務(wù)中通常采用UDP方式進(jìn)行實(shí)時(shí)數(shù)據(jù)傳輸20UPD頭2121TCP/IP網(wǎng)絡(luò)編程預(yù)備知識系統(tǒng)調(diào)用TCP編程/UDP編程API網(wǎng)絡(luò)封包格式和IP,TCP頭TCP握手過程I/O模型和服務(wù)器模型網(wǎng)絡(luò)調(diào)試和協(xié)議分析—wireshark和tcpdump使用22TCP/IP網(wǎng)絡(luò)編程預(yù)備知識SocketIP地址端口號字節(jié)序23Socket簡介1982-BerkeleySoftwareDistributions操作系統(tǒng)引入了socket作為本地進(jìn)程之間通信的接口1986-Berkeley擴(kuò)展了socket接口,使之支持UNIX下的TCP/IP通信現(xiàn)在很多應(yīng)用
(FTP,Telnet,etc)都依賴這一接口24Socket簡介Socket是一個(gè)編程接口是一種特殊的文件描述符(everythinginUnixisafile)并不僅限于TCP/IP協(xié)議面向連接
(TransmissionControlProtocol-TCP/IP)無連接(UserDatagramProtocol-UDP和
Inter-networkPacketExchange-IPX)
www
.25為什么需要Socket普通的I/O操作過程打開文件->讀/寫操作->關(guān)閉文件TCP/IP協(xié)議被集成到操作系統(tǒng)的內(nèi)核中,引入了新型的“I/O”操作進(jìn)行網(wǎng)絡(luò)通信的兩個(gè)進(jìn)程在不同的機(jī)器上,如何連接?網(wǎng)絡(luò)協(xié)議具有多樣性,如何進(jìn)行統(tǒng)一的操作需要一種通用的網(wǎng)絡(luò)編程接口:Socket26Socket類型流式套接字(SOCK_STREAM)提供了一個(gè)面向連接、可靠的數(shù)據(jù)傳輸服務(wù),數(shù)據(jù)無差錯(cuò)、無重復(fù)的發(fā)送且按發(fā)送順序接收。內(nèi)設(shè)置流量控制,避免數(shù)據(jù)流淹沒慢的接收方。數(shù)據(jù)被看作是字節(jié)流,無長度限制。數(shù)據(jù)報(bào)套接字(SOCK_DGRAM)提供無連接服務(wù)。數(shù)據(jù)包以獨(dú)立數(shù)據(jù)包的形式被發(fā)送,不提供無差錯(cuò)保證,數(shù)據(jù)可能丟失或重復(fù),順序發(fā)送,可能亂序接收。原始套接字(SOCK_RAW)可以對較低層次協(xié)議如IP、ICMP直接訪問。27IP地址IP地址是Internet中主機(jī)的標(biāo)識Internet中的主機(jī)要與別的機(jī)器通信必須具有一個(gè)IP地址IP地址為32位(IPv4)或者128位(IPv6)每個(gè)數(shù)據(jù)包都必須攜帶目的IP地址和源IP地址,路由器依靠此信息為數(shù)據(jù)包選擇路由表示形式:常用點(diǎn)分形式,如0,最后都會(huì)轉(zhuǎn)換為一個(gè)32位的無符號整數(shù)。IP地址分類子網(wǎng)掩碼28端口號為了區(qū)分一臺(tái)主機(jī)接收到的數(shù)據(jù)包應(yīng)該轉(zhuǎn)交給哪個(gè)進(jìn)程來進(jìn)行處理,使用端口號來區(qū)別TCP端口號與UDP端口號獨(dú)立端口號一般由IANA(InternetAssignedNumbersAuthority)管理眾所周知端口:1~1023(1~255之間為眾所周知端口,256~1023端口通常由UNIX系統(tǒng)占用)注冊端口:1024~49150動(dòng)態(tài)或私有端口:49151~6553529套接字和端口進(jìn)程-2TCPUDPIP(+ICMP)網(wǎng)絡(luò)層網(wǎng)線進(jìn)程-1進(jìn)程-4進(jìn)程-3端口內(nèi)核每個(gè)socket都和端口、協(xié)議相聯(lián)系30套接字和端口
tcpmux
…….系統(tǒng)分配的端口
171024-500021ftpecho
23telnet自己分配的端口
5001-65536保留的端口注冊的端口其他端口31字節(jié)序不同類型CPU的主機(jī)中,內(nèi)存存儲(chǔ)多字節(jié)整數(shù)序列有兩種方法,稱為主機(jī)字節(jié)序(HBO):小端序(little-endian)-低序字節(jié)存儲(chǔ)在低地址將低字節(jié)存儲(chǔ)在起始地址,稱為“Little-Endian”字節(jié)序,Intel、AMD等采用的是這種方式;大端序(big-endian)-高序字節(jié)存儲(chǔ)在低地址將高字節(jié)存儲(chǔ)在起始地址,稱為“Big-Endian”字節(jié)序,由ARM、Motorola等所采用網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù)必須按網(wǎng)絡(luò)字節(jié)序,即大端字節(jié)序在大部分PC機(jī)上,當(dāng)應(yīng)用進(jìn)程將整數(shù)送入socket前,需要轉(zhuǎn)化成網(wǎng)絡(luò)字節(jié)序;當(dāng)應(yīng)用進(jìn)程從socket取出整數(shù)后,要轉(zhuǎn)化成小端字節(jié)序(原因?)32字節(jié)序網(wǎng)絡(luò)字節(jié)序(NBO-NetworkByteOrder)使用統(tǒng)一的字節(jié)順序,避免兼容性問題主機(jī)字節(jié)序(HBO-HostByteOrder)不同的機(jī)器HBO是不一樣的,這與CPU的設(shè)計(jì)有關(guān)Motorola68K系列、ARM系列,HBO與NBO是一致的IntelX86系列,HBO與NBO不一致33字節(jié)序轉(zhuǎn)換函數(shù)把給定系統(tǒng)所采用的字節(jié)序稱為主機(jī)字節(jié)序。為了避免不同類別主機(jī)之間在數(shù)據(jù)交換時(shí)由于對于字節(jié)序的不同而導(dǎo)致的差錯(cuò),引入了網(wǎng)絡(luò)字節(jié)序。主機(jī)字節(jié)序到網(wǎng)絡(luò)字節(jié)序u_longhtonl(u_longhostlong);u_shorthtons(u_shortshort);網(wǎng)絡(luò)字節(jié)序到主機(jī)字節(jié)序u_longntohl(u_longhostlong);u_shortntohs(u_shortshort);34IP地址的轉(zhuǎn)換inet_aton()將strptr所指的字符串轉(zhuǎn)換成32位的網(wǎng)絡(luò)字節(jié)序二進(jìn)制值#include<arpa/inet.h>intinet_aton(constchar*strptr,structin_addr*addrptr);inet_addr()功能同上,返回轉(zhuǎn)換后的地址。int_addr_tinet_addr(constchar*strptr);inet_ntoa()將32位網(wǎng)絡(luò)字節(jié)序二進(jìn)制地址轉(zhuǎn)換成點(diǎn)分十進(jìn)制的字符串。char*inet_ntoa(stuctin_addrinaddr);inet_pton()將IPV4/IPV6的地址轉(zhuǎn)換成binary格式
intinet_pton(intaf,constchar*src,void*dst);35TCP/IP網(wǎng)絡(luò)編程預(yù)備知識系統(tǒng)調(diào)用TCP編程/UDP編程API網(wǎng)絡(luò)封包格式和IP,TCP頭TCP握手過程I/O模型和服務(wù)器模型網(wǎng)絡(luò)調(diào)試和協(xié)議分析—wireshark和tcpdump使用36網(wǎng)絡(luò)編程相關(guān)API網(wǎng)絡(luò)編程常用函數(shù)socket()創(chuàng)建套接字bind()綁定本機(jī)地址和端口connect()建立連接listen()設(shè)置監(jiān)聽端口accept()接受TCP連接recv(),read(),recvfrom()數(shù)據(jù)接收send(),write(),sendto()數(shù)據(jù)發(fā)送close(),shutdown()關(guān)閉套接字373838socketintsocket(intdomain,inttype,intprotocol);domain是地址族PF_INET//internet協(xié)議PF_UNIX//unixinternal協(xié)議PF_NS//XeroxNS協(xié)議PF_IMPLINK//InterfaceMessage協(xié)議type//套接字類型SOCK_STREAM//流式套接字SOCK_DGRAM//數(shù)據(jù)報(bào)套接字SOCK_RAW//原始套接字protocol參數(shù)通常置為039intsocket_fd=socket(AF_INET,SOCK_STREAM,0);“PF_INET”=使用網(wǎng)絡(luò)協(xié)議族“SOCK_STREAM”=使用
TCPreturnssocketIDonsuccessreturn-1onerror總是
0socket40
地址相關(guān)的數(shù)據(jù)結(jié)構(gòu)通用地址結(jié)構(gòu)
structsockaddr{
u_shortsa_family;//地址族,AF_xxx
charsa_data[14];//14字節(jié)協(xié)議地址
};Internet協(xié)議地址結(jié)構(gòu)
structsockaddr_in{u_shortsin_family;//地址族,AF_INET,2bytes
u_shortsin_port;//端口,2bytes
structin_addrsin_addr;//IPV4地址,4bytes
charsin_zero[8];//8bytesunused,作為填充
};
41
地址相關(guān)的數(shù)據(jù)結(jié)構(gòu)IPv4地址結(jié)構(gòu)//internetaddressstructin_addr{in_addr_ts_addr;//u32networkaddress};42bind()int
bind(int
sockfd,
struct
sockaddr
*my_addr,
int
addrlen);頭文件:#include<sys/types.h>#include<sys/socket.h>sockfd:socket調(diào)用返回的文件描述符
addrlen:sockaddr地址結(jié)構(gòu)的長度返回值:0或-143intstatus=bind(sockfd,(structsockaddr*)&my_addr,sizeof(my_addr));sockaddr_in
結(jié)構(gòu),描述本機(jī)的端口和
IP地址sockaddr_in
結(jié)構(gòu)的字節(jié)長度returncode(-1iferror)sockfdisreturnedbysocket()bind()44bindintbind(intsockfd,structsockaddr*addr,intaddrLen);sockfd
由socket()調(diào)用返回addr
是指向sockaddr_in結(jié)構(gòu)的指針,包含本機(jī)IP地址和端口號structsockaddr_inu_shortsin_family//protocolfamilyu_shortsin_port//portnumberstructin_addrsin_addr//IPaddress(32-bits)addrLen:sizeof(structsockaddr_in)45structsockaddr_inmy_addr;/*My(client)Internetaddress*//*SetMy(client's)IPAddress----------------------------------------*/my_addr.sin_family=PF_INET;/*ProtocolFamilyToBeUsed*/my_addr.sin_port=htons(6666);/*Portnumbertouse*/my_addr.sin_addr.s_addr=inet_addr(“00”);/*MyIPaddress*/
Step1:初始化該數(shù)據(jù)結(jié)構(gòu)Step2:填充信息howtofilladdrinfo46地址結(jié)構(gòu)的一般用法定義一個(gè)structsockaddr_in類型的變量并清空structsockaddr_inmyaddr;memset(&myaddr,0,sizeof(myaddr));填充地址信息myaddr.sin_family=PF_INET;myaddr.sin_port=htons(8888);myaddr.sin_addr.s_addr=inet_addr(“00”);將該變量強(qiáng)制轉(zhuǎn)換為structsockaddr類型在函數(shù)中使用bind(listenfd,(structsockaddr*)(&myaddr),sizeof(myaddr));47unsignedlonginet_addr(char*address);address是以’\0’結(jié)尾的點(diǎn)分IPv4字符串。該函數(shù)返回32位的地址。如果字符串包含的不是合法的IP地址,則函數(shù)返回-1。例如:structin_addraddr;addr.s_addr=inet_addr("00");char*inet_ntoa(structin_addraddress);address是IPv4地址結(jié)構(gòu),函數(shù)返回一指向包含點(diǎn)分IP地址的靜態(tài)存儲(chǔ)區(qū)字符指針。如果錯(cuò)誤則函數(shù)返回NULL地址轉(zhuǎn)換函數(shù)48listen
intlisten(intsockfd,intbacklog);sockfd:監(jiān)聽連接的套接字backlog指定了正在等待連接的最大隊(duì)列長度,它的作用在于處理可能同時(shí)出現(xiàn)的幾個(gè)連接請求。DoS(拒絕服務(wù))攻擊即利用了這個(gè)原理,非法的連接占用了全部的連接數(shù),造成正常的連接請求被拒絕。返回值:
0或-1完成listen()調(diào)用后,socket變成了監(jiān)聽socket(listeningsocket).49accept()int
accept(int
sockfd,
struct
sockaddr
*addr,socklen_t
*addrlen);返回值:已建立好連接的套接字或-1頭文件#include<sys/types.h>#include<sys/socket.h>
sockfd:監(jiān)聽套接字addr:對方地址addrlen:地址長度listen()和accept()是TCP服務(wù)器端使用的函數(shù)50intnew_accepted_fd=accept(listen_fd,(structsockaddr*)client_addr,指針:接收連接的sockaddr_in結(jié)構(gòu)體的長度一個(gè)新的已連接的socket(-1iferror)接受客戶連接的socket,即listeningsocketclient_addr_length);接收外來連接的地址信息,如果不關(guān)心,可置為NULLaccept()函數(shù)51connect()int
connect(int
sockfd,
struct
sockaddr
*serv_addr,int
addrlen);返回值:0或-1頭文件:#include<sys/types.h>#include<sys/socket.h>
sockfd:socket返回的文件描述符serv_addr:服務(wù)器端的地址信息
addrlen:serv_addr的長度
connect()是客戶端使用的系統(tǒng)調(diào)用。52intstatus=connect(socket_fd,(structsockaddr*)&addr,sizeof(addr));structsockaddr結(jié)構(gòu),描述服務(wù)器的端口和
IP地址structsockaddr
結(jié)構(gòu)的字節(jié)長度returncode(-1iferror)socket_fdreturnedbysocket()systemcallconnect()函數(shù)53send()ssize_tsend(intsocket,constvoid*buffer,size_tlength,intflags);返回值:成功:實(shí)際發(fā)送的字節(jié)數(shù)失敗:-1,并設(shè)置errno頭文件:#include<sys/socket.h>buffer:發(fā)送緩沖區(qū)首地址length:發(fā)送的字節(jié)數(shù)flags:發(fā)送方式(通常為0)54intstatus=send(socket_fd,out_buffer,MAX_BUFFER_SIZE,0);returncode(-1iferror)socketreturnedbysocket()oraccept()Always0Themaximumbuffersize待發(fā)送數(shù)據(jù)緩沖區(qū)的指針onsuccess,thenumberofbytesactuallysentsend()函數(shù)55recv()ssize_trecv(intsocket,constvoid*buffer,size_tlength,intflags);返回值:成功:實(shí)際接收的字節(jié)數(shù)失?。?1,并設(shè)置errno頭文件:#include<sys/socket.h>buffer:發(fā)送緩沖區(qū)首地址length:發(fā)送的字節(jié)數(shù)flags:接收方式(通常為0)56intstatus=recv(socket_fd,in_buffer,MAX_BUFFER_SIZE,0);returncode(-1iferror)Always0Themaximumbuffersize接收數(shù)據(jù)的緩沖區(qū)的指針Example:charin_buffer[MAX_BUFFER]Socketfdreturnedbysocket()callonsuccess,thenumberofbytesreceivedrecv()函數(shù)57read()/write()ssize_tread(intfd,void*buf,size_tcount);ssize_twrite(intfd,constvoid*buf,size_tcount);read()和write()經(jīng)常會(huì)代替recv()和send(),通常情況下,看程序員的偏好使用read()/write()和recv()/send()時(shí)最好統(tǒng)一58sendto(),recvfrom()ssize_tsendto(intsocket,void*message,size_tlength,intflags,structsockaddr*dest_addr,socklen_tdest_len);ssize_trecvfrom(intsocket,void*buffer,size_tlength,intflags,structsockaddr*address,socklen_t*address_len);這兩個(gè)函數(shù)一般在使用UDP協(xié)議時(shí)使用592.TCP/IP網(wǎng)絡(luò)編程預(yù)備知識系統(tǒng)調(diào)用TCP編程/UDP編程API網(wǎng)絡(luò)封包格式和IP,TCP頭TCP握手過程I/O模型和服務(wù)器模型網(wǎng)絡(luò)調(diào)試和協(xié)議分析—wireshark和tcpdump使用60TCP編程API61UDP編程API622.TCP/IP網(wǎng)絡(luò)編程預(yù)備知識系統(tǒng)調(diào)用TCP編程/UDP編程API網(wǎng)絡(luò)封包格式和IP,TCP頭TCP握手過程I/O模型和服務(wù)器模型網(wǎng)絡(luò)調(diào)試和協(xié)議分析—wireshark和tcpdump使用63TCP/IP協(xié)議網(wǎng)絡(luò)封包格式EthernetheaderIPheaderTCPheaderApp.headerUserdataEthernettrailer14202046-1500642.TCP/IP網(wǎng)絡(luò)編程預(yù)備知識系統(tǒng)調(diào)用TCP編程/UDP編程API網(wǎng)絡(luò)封包格式和IP,TCP頭TCP握手過程I/O模型和服務(wù)器模型網(wǎng)絡(luò)調(diào)試和協(xié)議分析—wireshark和tcpdump使用65TCP三次/四次握手662.TCP/IP網(wǎng)絡(luò)編程預(yù)備知識系統(tǒng)調(diào)用TCP編程/UDP編程API網(wǎng)絡(luò)封包格式和IP,TCP頭TCP握手過程I/O模型和服務(wù)器模型網(wǎng)絡(luò)調(diào)試和協(xié)議分析—wireshark和tcpdump使用67IO模型
在UNIX/Linux下主要有4種I/O模型:阻塞I/O:最常用、最簡單、效率最低非阻塞I/O:可防止進(jìn)程阻塞在I/O操作上,需要輪詢I/O多路復(fù)用:允許同時(shí)對多個(gè)I/O進(jìn)行控制信號驅(qū)動(dòng)I/O:一種異步通信模型68阻塞I/O模式阻塞I/O模式是最普遍使用的I/O模式,大部分程序使用的都是阻塞模式的I/O。缺省情況下,套接字建立后所處于的模式就是阻塞I/O模式。前面學(xué)習(xí)的很多讀寫函數(shù)在調(diào)用過程中會(huì)發(fā)生阻塞。讀操作中的read、recv、recvfrom寫操作中的write、send其他操作:accept、connect69讀阻塞以read函數(shù)為例:進(jìn)程調(diào)用read函數(shù)從套接字上讀取數(shù)據(jù),當(dāng)套接字的接收緩沖區(qū)中還沒有數(shù)據(jù)可讀,函數(shù)read將發(fā)生阻塞。它會(huì)一直阻塞下去,等待套接字的接收緩沖區(qū)中有數(shù)據(jù)可讀。經(jīng)過一段時(shí)間后,緩沖區(qū)內(nèi)接收到數(shù)據(jù),于是內(nèi)核便去喚醒該進(jìn)程,通過read訪問這些數(shù)據(jù)。如果在進(jìn)程阻塞過程中,對方發(fā)生故障,那這個(gè)進(jìn)程將永遠(yuǎn)阻塞下去。70寫阻塞在寫操作時(shí)發(fā)生阻塞的情況要比讀操作少。主要發(fā)生在要寫入的緩沖區(qū)的大小小于要寫入的數(shù)據(jù)量的情況下。這時(shí),寫操作不進(jìn)行任何拷貝工作,將發(fā)生阻塞。一量發(fā)送緩沖區(qū)內(nèi)有足夠的空間,內(nèi)核將喚醒進(jìn)程,將數(shù)據(jù)從用戶緩沖區(qū)中拷貝到相應(yīng)的發(fā)送數(shù)據(jù)緩沖區(qū)。UDP不用等待確認(rèn),沒有實(shí)際的發(fā)送緩沖區(qū),所以UDP協(xié)議中不存在發(fā)送緩沖區(qū)滿的情況,在UDP套接字上執(zhí)行的寫操作永遠(yuǎn)都不會(huì)阻塞。71非阻塞模式I/O當(dāng)我們將一個(gè)套接字設(shè)置為非阻塞模式,我們相當(dāng)于告訴了系統(tǒng)內(nèi)核:“當(dāng)我請求的I/O操作不能夠馬上完成,你想讓我的進(jìn)程進(jìn)行休眠等待的時(shí)候,不要這么做,請馬上返回一個(gè)錯(cuò)誤給我?!碑?dāng)一個(gè)應(yīng)用程序使用了非阻塞模式的套接字,它需要使用一個(gè)循環(huán)來不停地測試是否一個(gè)文件描述符有數(shù)據(jù)可讀(稱做polling)。應(yīng)用程序不停的polling內(nèi)核來檢查是否I/O操作已經(jīng)就緒。這將是一個(gè)極浪費(fèi)CPU資源的操作。這種模式使用中不普遍。72非阻塞模式I/O套接字緩沖區(qū)中沒有數(shù)據(jù)……套接字緩沖區(qū)中數(shù)據(jù)到達(dá),進(jìn)行數(shù)據(jù)復(fù)制用戶態(tài)核心態(tài)readread返回readreadread返回read返回多次調(diào)用read后EWOULDBLOCKEWOULDBLOCK讀到數(shù)據(jù)套接字緩沖區(qū)中沒有數(shù)據(jù)73多路復(fù)用I/O應(yīng)用程序中同時(shí)處理多路輸入輸出流,若采用阻塞模式,將得不到預(yù)期的目的;若采用非阻塞模式,對多個(gè)輸入進(jìn)行輪詢,但又太浪費(fèi)CPU時(shí)間;若設(shè)置多個(gè)進(jìn)程,分別處理一條數(shù)據(jù)通路,將新產(chǎn)生進(jìn)程間的同步與通信問題,使程序變得更加復(fù)雜;比較好的方法是使用I/O多路復(fù)用。其基本思想是:先構(gòu)造一張有關(guān)描述符的表,然后調(diào)用一個(gè)函數(shù)。當(dāng)這些文件描述符中的一個(gè)或多個(gè)已準(zhǔn)備好進(jìn)行I/O時(shí)函數(shù)才返回。函數(shù)返回時(shí)告訴進(jìn)程那個(gè)描述符已就緒,可以進(jìn)行I/O操作。74select()/poll()實(shí)現(xiàn)多路復(fù)用#include<sys/poll.h>intpoll(structpollfd*ufds,unsignedintnfds,inttimeout);#include<sys/time.h>#include<sys/types.h>#include<unistd.h>intselect(intn,fd_set*read_fds,fd_set*write_fds,fd_set*except_fds,structtimeval*timeout);75select()參數(shù)maxfd所有監(jiān)控的文件描述符中最大的那一個(gè)加1read_fds所有要讀的文件文件描述符的集合write_fds所有要的寫文件文件描述符的集合except_fds其他要向我們通知的文件描述符timeout超時(shí)設(shè)置.Null:一直阻塞,直到有文件描述符就緒或出錯(cuò)時(shí)間值為0:僅僅檢測文件描述符集的狀態(tài),然后立即返回時(shí)間值不為0:在指定時(shí)間內(nèi),如果沒有事件發(fā)生,則超時(shí)返回。76函數(shù)select在我們調(diào)用select時(shí)進(jìn)程會(huì)一直阻塞直到以下的一種情況發(fā)生.有文件可以讀.有文件可以寫.超時(shí)所設(shè)置的時(shí)間到.為了設(shè)置文件描述符我們要使用幾個(gè)宏:FD_SET將fd加入到fdsetFD_CLR將fd從fdset里面清除FD_ZERO從fdset中清除所有的文件描述符FD_ISSET判斷fd是否在fdset集合中77select宏的形式:voidFD_ZERO(fd_set*fdset)voidFD_SET(intfd,fd_set*fdset)voidFD_CLR(intfd,fd_set*fdset)intFD_ISSET(intfd,fd_set*fdset)
78TCP多路復(fù)用關(guān)鍵點(diǎn):
1.select()函數(shù)里面的各個(gè)文件描述符fd_set集合的參數(shù)在select()前后發(fā)生了變化:前:表示關(guān)心的文件描述符集合后:有數(shù)據(jù)的集合(如不是在超時(shí)還回情況下)
2.那么究竟是誰動(dòng)了fd_set集合的奶酪?答曰:kernel
思考:
這種模式下,多路網(wǎng)絡(luò)連接時(shí)候能否真正多路并發(fā)處理?如果能,請說明理由,如不能,請給出改進(jìn)意見79select實(shí)例
參見SelectDEMO803.網(wǎng)絡(luò)編程高級話題網(wǎng)絡(luò)信息檢索、網(wǎng)絡(luò)屬性設(shè)置和超時(shí)檢測TCP帶外數(shù)據(jù)及編程方法廣播和組播UNIX域套接字81網(wǎng)絡(luò)信息檢索函數(shù)gethostname()獲得主機(jī)名getpeername()獲得與套接口相連的遠(yuǎn)程協(xié)議地址getsockname()獲得本地套接口協(xié)議地址gethostbyname()根據(jù)主機(jī)名取得主機(jī)信息
endhostent()gethostbyaddr()根據(jù)主機(jī)地址取得主機(jī)信息getprotobyname()根據(jù)協(xié)議名取得主機(jī)協(xié)議信息getprotobynumber()根據(jù)協(xié)議號取得主機(jī)協(xié)議信息getservbyname()根據(jù)服務(wù)名取得相關(guān)服務(wù)信息getservbyport()根據(jù)端口號取得相關(guān)服務(wù)信息82網(wǎng)絡(luò)屬性設(shè)置getsockopt和setsockopt
intgetsockopt(intsockfd,intlevel,intoptname,void*optval,socklen_t*optlen)intsetsockopt(intsockfd,intlevel,intoptname,constvoid*optval,socklen_t*optlen)level指定控制套接字的層次.可以取三種值:
1)SOL_SOCKET:通用套接字選項(xiàng).
2)IPPROTO_IP:IP選項(xiàng).
3)IPPROTO_TCP:TCP選項(xiàng).
optname指定控制的方式(選項(xiàng)的名稱),我們下面詳細(xì)解釋optval獲得或者是設(shè)置套接字選項(xiàng).根據(jù)選項(xiàng)名稱的數(shù)據(jù)類型進(jìn)行轉(zhuǎn)換83選項(xiàng)名稱說明數(shù)據(jù)類型
========================================================================
SOL_SOCKET
------------------------------------------------------------------------
SO_BROADCAST允許發(fā)送廣播數(shù)據(jù)int
SO_DEBUG允許調(diào)試int
SO_DONTROUTE不查找路由int
SO_ERROR獲得套接字錯(cuò)誤int
SO_KEEPALIVE
保持連接int
SO_LINGER延遲關(guān)閉連接structlinger
SO_OOBINLINE帶外數(shù)據(jù)放入正常數(shù)據(jù)流int
SO_RCVBUF接收緩沖區(qū)大小int
SO_SNDBUF發(fā)送緩沖區(qū)大小int
SO_RCVLOWAT接收緩沖區(qū)下限int
SO_SNDLOWAT發(fā)送緩沖區(qū)下限int
SO_RCVTIMEO接收超時(shí)structtimeval
SO_SNDTIMEO發(fā)送超時(shí)structtimeval
SO_REUSERADDR允許重用本地地址和端口int
SO_TYPE獲得套接字類型int
SO_BSDCOMPAT與BSD系統(tǒng)兼容int
==========================================================================
IPPROTO_IP
-------------------------------------------------------------------------------------------------------------------------------IP_HDRINCL在數(shù)據(jù)包中包含IP首部int
IP_OPTINOS
IP首部選項(xiàng)int
IP_TOS服務(wù)類型
IP_TTL生存時(shí)間int
==========================================================================
IPPRO_TCP
-----------------------------------------------------------------------------------------------------------------------------
TCP_MAXSEG
TCP最大數(shù)據(jù)段的大小int
TCP_NODELAY不使用Nagle算法int
==========================================================84網(wǎng)絡(luò)超時(shí)在網(wǎng)絡(luò)通信中,很多操作會(huì)使得進(jìn)程阻塞TCP套接字中的recv/accept/connectUDP套接字中的recvfrom超時(shí)檢測的必要性避免進(jìn)程在沒有數(shù)據(jù)時(shí)無限制地阻塞當(dāng)設(shè)定的時(shí)間到時(shí),進(jìn)程從原操作返回繼續(xù)運(yùn)行85網(wǎng)絡(luò)超時(shí)檢測(一)設(shè)置socket的屬性SO_RCVTIMEO參考代碼如下
structtimevaltv;
tv.tv_sec=5;//設(shè)置5秒時(shí)間
tv.tv_usec=0;setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv));//設(shè)置接收超時(shí)
recv()/recvfrom()//從socket讀取數(shù)據(jù)86網(wǎng)絡(luò)超時(shí)檢測(二)用select檢測socket是否’ready’參考代碼如下
structfd_setrdfs;
structtimevaltv={5,0};//設(shè)置5秒時(shí)間
FD_ZERO(&rdfs);FD_SET(sockfd,&rdfs);if(select(sockfd+1,&rdfs,NULL,NULL,&tv)>0)//socket就緒
{recv()/recvfrom()//從socket讀取數(shù)據(jù)
}873.網(wǎng)絡(luò)編程高級話題網(wǎng)絡(luò)信息檢索、網(wǎng)絡(luò)屬性設(shè)置和超時(shí)檢測TCP帶外數(shù)據(jù)及編程方法廣播和組播UNIX域套接字88廣播前面介紹的數(shù)據(jù)包發(fā)送方式只有一個(gè)接受方,稱為單播如果同時(shí)發(fā)給局域網(wǎng)中的所有主機(jī),稱為廣播只有用戶數(shù)據(jù)報(bào)(使用UDP協(xié)議)套接字才能廣播廣播地址以()網(wǎng)段為例,最大的主機(jī)地址55代表該網(wǎng)段的廣播地址發(fā)到該地址的數(shù)據(jù)包被所有的主機(jī)接收55在所有網(wǎng)段中都代表廣播地址89廣播發(fā)送創(chuàng)建用戶數(shù)據(jù)報(bào)套接字缺省創(chuàng)建的套接字不允許廣播數(shù)據(jù)包,需要設(shè)置屬性setsockopt可以設(shè)置套接字屬性接收方地址指定為廣播地址指定端口信息發(fā)送數(shù)據(jù)包90setsockoptintsetsockopt(ints,intlevel,intoptname,constvoid*optval,socklen_toptlen);頭文件:<sys/socket.h>level:選項(xiàng)級別(例如SOL_SOCKET)optname:選項(xiàng)名(例如SO_BROADCAST)optval:存放選項(xiàng)值的緩沖區(qū)的地址optlen:緩沖區(qū)長度返回值:成功返回0失敗返回-1并設(shè)置errno91廣播發(fā)送示例sockfd=socket(,,);……inton=1;setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));……sendto(;;;;;);92廣播接收創(chuàng)建用戶數(shù)據(jù)報(bào)套接字綁定本機(jī)IP地址和端口綁定的端口必須和發(fā)送方指定的端口相同等待接收數(shù)據(jù)93組播單播方式只能發(fā)給一個(gè)接收方。廣播方式發(fā)給所有的主機(jī)。過多的廣播會(huì)大量占用網(wǎng)絡(luò)帶寬,造成廣播風(fēng)暴,影響正常的通信。組播(又稱為多播)是一種折中的方式。只有加入某個(gè)多播組的主機(jī)才能收到數(shù)據(jù)。多播方式既可以發(fā)給多個(gè)主機(jī),又能避免象廣播那樣帶來過多的負(fù)載(每臺(tái)主機(jī)要到傳輸層才能判斷廣播包是否要處理)94組播發(fā)送創(chuàng)建用戶數(shù)據(jù)報(bào)套接字接收方地址指定為組播地址指定端口信息發(fā)送數(shù)據(jù)包95組播接收創(chuàng)建用戶數(shù)據(jù)報(bào)套接字加入多播組綁定本機(jī)IP地址和端口綁定的端口必須和發(fā)送方指定的端口相同等待接收數(shù)據(jù)96加入多播組structip_m
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 參加教師培訓(xùn)心得(5篇)
- 營銷的培訓(xùn)心得5篇
- 生活垃圾資源化處理項(xiàng)目可行性研究報(bào)告
- 幼兒園家園共育工作計(jì)劃(3篇)
- 高三的精彩演講稿800字怎么寫(素材稿件8篇)
- 財(cái)務(wù)部員工工作總結(jié)范文(10篇)
- 年會(huì)員工個(gè)人發(fā)言稿范文10篇(全文)
- 居住小區(qū)景觀養(yǎng)護(hù)服務(wù)合同
- 費(fèi)用報(bào)銷政策
- 小學(xué)二年級學(xué)生家長會(huì)講話稿5篇
- 湖南美術(shù)出版社六年級上冊《書法練習(xí)指導(dǎo)》表格教案
- 投標(biāo)項(xiàng)目進(jìn)度計(jì)劃
- 中醫(yī)腦病科缺血性中風(fēng)(腦梗死恢復(fù)期)中醫(yī)診療方案臨床療效分析總結(jié)
- 部編版語文二年級上冊《語文園地三我喜歡的玩具》(教案)
- 軟件開發(fā)項(xiàng)目驗(yàn)收方案
- 崗位整合整治與人員優(yōu)化配置實(shí)施細(xì)則
- 康復(fù)治療技術(shù)的職業(yè)規(guī)劃課件
- 蜜雪冰城營銷案例分析總結(jié)
- 交換機(jī)CPU使用率過高的原因分析及探討
- 易制毒化學(xué)品安全管理崗位責(zé)任分工制度
- 住宿服務(wù)免責(zé)聲明
評論
0/150
提交評論