![課件資源等9unixlinux網(wǎng)絡(luò)編程socket通信_(tái)第1頁](http://file4.renrendoc.com/view/583d43832874eb0c60b9a314e4628d3b/583d43832874eb0c60b9a314e4628d3b1.gif)
![課件資源等9unixlinux網(wǎng)絡(luò)編程socket通信_(tái)第2頁](http://file4.renrendoc.com/view/583d43832874eb0c60b9a314e4628d3b/583d43832874eb0c60b9a314e4628d3b2.gif)
![課件資源等9unixlinux網(wǎng)絡(luò)編程socket通信_(tái)第3頁](http://file4.renrendoc.com/view/583d43832874eb0c60b9a314e4628d3b/583d43832874eb0c60b9a314e4628d3b3.gif)
![課件資源等9unixlinux網(wǎng)絡(luò)編程socket通信_(tái)第4頁](http://file4.renrendoc.com/view/583d43832874eb0c60b9a314e4628d3b/583d43832874eb0c60b9a314e4628d3b4.gif)
![課件資源等9unixlinux網(wǎng)絡(luò)編程socket通信_(tái)第5頁](http://file4.renrendoc.com/view/583d43832874eb0c60b9a314e4628d3b/583d43832874eb0c60b9a314e4628d3b5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
Unix/Linux網(wǎng)絡(luò)編程講師:朱景堯C語言C++語言傳智播客
高薪就業(yè)ContentsTCP/IP與socketUDP通信TCP通信123非阻塞socket與epoll4小竅門
5第一章TCP/IP與socket
以前我們講過進(jìn)程間通信,通過進(jìn)程間通信可以實(shí)現(xiàn)同一臺(tái)計(jì)算機(jī)上不同的進(jìn)程之間通信。通過網(wǎng)絡(luò)編程可以實(shí)現(xiàn)在網(wǎng)絡(luò)中的各個(gè)計(jì)算機(jī)之間的通信。進(jìn)程能夠使用socket實(shí)現(xiàn)和其他進(jìn)程或者其他計(jì)算機(jī)通信。同樣的socket既可以實(shí)現(xiàn)進(jìn)程間通信,也可以實(shí)現(xiàn)計(jì)算機(jī)之間通信。第一章TCP/IP與socket
socket是通信端點(diǎn)的抽象。與文件描述符一樣,socket需要使用socket描述符。socket在Linux上也是通過文件實(shí)現(xiàn)的,所以傳統(tǒng)的write和read同樣適用于socket。當(dāng)服務(wù)器和應(yīng)用程序需要和其他進(jìn)程通信的時(shí)候就會(huì)使用socket。一對(duì)對(duì)接的socket構(gòu)成了進(jìn)程間交流數(shù)據(jù)的一個(gè)通道。這些進(jìn)程可能是windows或者linux以及IOS,android都可以互相通信。第一章TCP/IP與socket
通信域用來說明socket通信協(xié)議的語義。每個(gè)域都定義了一套協(xié)議、控制和解釋名字規(guī)則,以及socket的地址格式。對(duì)于internet域來講,socket地址格式是一個(gè)IP地址和端口號(hào)。internet域socket用于連網(wǎng)通信,它們可以用在幾乎任何支持TCP/IP的網(wǎng)絡(luò)通信程序上。ContentsTCP/IP與socketUDP通信TCP通信123非阻塞socket與epoll4小竅門
5第二章UDP通信
一個(gè)程序使用UDPsocket需要執(zhí)行3個(gè)步驟。初始化socket。發(fā)送或接收數(shù)據(jù)。關(guān)閉socket。涉及到的調(diào)用包括socket、bind、recvfrom、sendto。第二章UDP通信
初始化socket。我們需要做的第一件工作就是初始化socket。socket可以看做是文件描述符。不論是接收端,還是發(fā)送端,第一步都是一樣的。每個(gè)socket都是一個(gè)通信的通道第二章UDP通信#include<sys/types.h>#include<sys/socket.h>intsocket(intdomain,inttype,intprotocol);系統(tǒng)調(diào)用socket帶有以下參數(shù)protocol(這個(gè)值一般都取0)。成功返回socket描述符,失敗返回-1,并設(shè)置errno第二章UDP通信
domain說明。值說明AF_UNIXUNIX內(nèi)部使用AF_INETTCP/IP協(xié)議AF_ISO國際標(biāo)準(zhǔn)組織協(xié)議AF_NSXerox網(wǎng)絡(luò)協(xié)議第二章UDP通信
type說明。值說明SOCK_STREAM使用TCP可靠連接SOCK_DGRAM使用UDP不可靠連接第二章UDP通信
使用UDP發(fā)送數(shù)據(jù)。ssize_tsendto(ints,constvoid*buf,size_tlen,intflags,conststructsockaddr*to,socklen_ttolen);第二章UDP通信
UDP發(fā)送數(shù)據(jù)例子intmain(intarg,char*args[]){ intst=socket(AF_INET,SOCK_DGRAM,0); if(st==-1) { printf("socketfailed%s\n",strerror(errno)); return0; } inton=1; if(setsockopt(st,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on))==-1) { printf("setsockoptfailed%s\n",strerror(errno)); returnEXIT_FAILURE; } structsockaddr_inaddr; memset(&addr,0,sizeof(addr)); addr.sin_family=AF_INET; addr.sin_port=htons(8080); addr.sin_addr.s_addr=inet_addr(args[1]); charbuf[1024]; while(1) { memset(buf,0,sizeof(buf)); read(STDIN_FILENO,buf,sizeof(buf)); if(sendto(st,buf,strlen(buf),0,(structsockaddr*)&addr, sizeof(addr))==-1) { printf("sendtofailed%s\n",strerror(errno)); break; } } close(st); returnEXIT_SUCCESS;}第二章UDP通信
intbind(intsockfd,conststructsockaddr*my_addr,socklen_taddrlen);bind將進(jìn)程和一個(gè)socket聯(lián)系起來,bind通常用于服務(wù)器進(jìn)程為接入客戶連接建立一個(gè)socket。參數(shù)sockfd是函數(shù)socket調(diào)用返回的socket描述符。參數(shù)my_addr是結(jié)構(gòu)sockaddr的地址。參數(shù)addrlen設(shè)置了my_addr能容納的最大字節(jié)數(shù)。成功返回0,失敗返回-1,并設(shè)置errno第二章UDP通信
使用UDP接收數(shù)據(jù)。ssize_trecvfrom(ints,void*buf,size_tlen,intflags, structsockaddr*from,socklen_t*fromlen);UDP接收數(shù)據(jù)之前需要調(diào)用bind。第二章UDP通信
UDP接收數(shù)據(jù)例子intmain(void){ intst=socket(AF_INET,SOCK_DGRAM,0); if(st==-1) { printf("socketfailed%s\n",strerror(errno)); return0; } structsockaddr_inaddr; memset(&addr,0,sizeof(addr)); addr.sin_family=AF_INET; addr.sin_port=htons(8080); addr.sin_addr.s_addr=htonl(INADDR_ANY); if(bind(st,(structsockaddr*)&addr,sizeof(addr))==-1) { printf("bindfailed%s\n",strerror(errno)); return-1; } charbuf[1024]; structsockaddr_inclient_addr; socklen_tlen=sizeof(client_addr); while(1) { memset(&client_addr,0,sizeof(client_addr)); memset(buf,0,sizeof(buf)); if(recvfrom(st,buf,sizeof(buf),0, (structsockaddr*)&client_addr,&len)==-1) { printf("recvfromfailed%s\n",strerror(errno)); break; }else { printf("%srecvis%s\n",inet_ntoa(client_addr.sin_addr),buf); } } close(st); return0;}第二章UDP通信
最后當(dāng)你用完socket以后,就該釋放socket所占用的資源了,通過close做到這一點(diǎn)。close。當(dāng)試圖向一個(gè)已經(jīng)關(guān)閉的socket寫或者讀數(shù)據(jù)就會(huì)出錯(cuò)。ContentsTCP/IP與socketUDP通信TCP通信123非阻塞socket與epoll4小竅門
5第三章TCP通信
使用TCP與UDP所用的代碼基本類似,唯一的區(qū)別在于socket函數(shù)調(diào)用的時(shí)候的一個(gè)參數(shù)的不同。intsocket(intdomain,inttype,intprotocol);參數(shù)type為SOCK_STREAM代表TCP,SOCK_DGRAM代表UDP。第三章TCP通信
一個(gè)程序使用TCPsocket需要執(zhí)行4個(gè)步驟。分配socket和初始化。連接。發(fā)送或接收數(shù)據(jù)。關(guān)閉socket。涉及到的調(diào)用包括socket、bind、listen、connect、accept、recv、send。第三章TCP通信-分配socket
分配socket和初始化。我們需要做的第一件工作就是分配socket。socket可以看做是文件描述符。不論是server端,還是client端,第一步都是一樣的。每個(gè)socket都是一個(gè)通信的通道TCP通信需要先建立連接,才能接收發(fā)送數(shù)據(jù)。第三章TCP通信-分配socket
intbind(intsockfd,conststructsockaddr*my_addr,socklen_taddrlen);bind將進(jìn)程和一個(gè)socket聯(lián)系起來,bind通常用于服務(wù)器進(jìn)程為接入客戶連接建立一個(gè)socket。參數(shù)sockfd是函數(shù)socket調(diào)用返回的socket值。參數(shù)my_addr是結(jié)構(gòu)sockaddr的地址。參數(shù)addrlen設(shè)置了my_addr能容納的最大字節(jié)數(shù)。成功返回0,失敗返回-1,并設(shè)置errno第三章TCP通信
對(duì)于客戶端程序,下一步是要與之通信的服務(wù)器建立連接??蛻舳酥恍枋褂胏onnect即可對(duì)于服務(wù)端程序,就是要建立自己的socket等待來自客戶端的連接。服務(wù)端需要調(diào)用listen和accept兩個(gè)函數(shù)。第三章TCP通信
intlisten(intsockfd,intbacklog);創(chuàng)建了socket并且使用bind將它和一個(gè)進(jìn)程關(guān)聯(lián)起來以后,服務(wù)端就需要調(diào)用listen來監(jiān)聽指定端口的客戶端連接。參數(shù)sockfd是調(diào)用socket返回的socket描述符參數(shù)backlog設(shè)置接入隊(duì)列的大小,通常把這個(gè)值設(shè)置的最夠大就可以了。成功返回0,失敗返回-1,并設(shè)置errno。第三章TCP通信
intaccept(intsockfd,structsockaddr*addr,socklen_t*addrlen);
當(dāng)有客戶端連接到服務(wù)端,它們會(huì)排入隊(duì)列,直到服務(wù)端準(zhǔn)備好處理它們?yōu)橹?,accept會(huì)返回一個(gè)新的socket,同時(shí)原來的socket繼續(xù)listen指定端口號(hào)。參數(shù)sockfd是調(diào)用socket返回的socket描述符參數(shù)addr指向結(jié)構(gòu)sockaddr地址。參數(shù)addrlen設(shè)置了addr能容納的最大字節(jié)數(shù)。成功返回新的socket,失敗返回-1,并設(shè)置errno。第三章TCP通信
intconnect(intsockfd,conststructsockaddr*serv_addr,socklen_taddrlen);
客戶端調(diào)用connect與服務(wù)端進(jìn)行連接。參數(shù)sockfd是調(diào)用socket返回的socket描述符。參數(shù)addr指向結(jié)構(gòu)sockaddr地址。參數(shù)addrlen設(shè)置了addr能容納的最大字節(jié)數(shù)。成功返回0,失敗返回-1,并設(shè)置errno。第三章TCP通信-傳送數(shù)據(jù)
客戶端和服務(wù)端建立了連接就可以在客戶端和服務(wù)端之間傳輸數(shù)據(jù)了,需要兩個(gè)系統(tǒng)調(diào)用。send---發(fā)送數(shù)據(jù)。recv---接收數(shù)據(jù)。一個(gè)socket既可以發(fā)送數(shù)據(jù),也可以接收數(shù)據(jù)。第三章TCP通信-傳送數(shù)據(jù)
ssize_tsend(ints,constvoid*buf,size_tlen,intflags);
send函數(shù)用來發(fā)送數(shù)據(jù)。參數(shù)s是已經(jīng)建立連接的socket。參數(shù)buf是接收數(shù)據(jù)內(nèi)存buffer地址指針。參數(shù)len指明buffer的大小,單位字節(jié)。參數(shù)flags一般填0。。成功返回發(fā)送的字節(jié)數(shù),失敗返回-1,并設(shè)置errno。第三章TCP通信-傳送數(shù)據(jù)
ssize_trecv(ints,void*buf,size_tlen,intflags);
recv函數(shù)用來接收數(shù)據(jù)。參數(shù)s是已經(jīng)建立連接的socket。參數(shù)buf是接收數(shù)據(jù)內(nèi)存buffer地址指針。參數(shù)len指明buffer的大小,單位字節(jié)。參數(shù)flags一般填0。。成功返回接收到的字節(jié)數(shù),失敗返回-1,如果對(duì)端socket已經(jīng)關(guān)閉,返回0。第三章TCP通信-關(guān)閉
最后當(dāng)你用完socket以后,就該釋放socket所占用的資源了,通過close做到這一點(diǎn)。close。當(dāng)試圖向一個(gè)已經(jīng)關(guān)閉的socket寫或者讀數(shù)據(jù)就會(huì)出錯(cuò)。第三章TCP通信
客戶端程序例子。需要包含頭文件#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>intmain(intarg,char*args[]){ intst=socket(AF_INET,SOCK_STREAM,0); structsockaddr_inaddr; memset(&addr,0,sizeof(addr)); addr.sin_family=AF_INET; addr.sin_port=htons(8080); addr.sin_addr.s_addr=inet_addr(""); if(connect(st,(structsockaddr*)&addr,sizeof(addr))==-1) { printf("connectfailed%s\n",strerror(errno)); returnEXIT_FAILURE; } chars[1024]; memset(s,0,sizeof(1024)); strcpy(s,"helloworld"); if(send(st,s,sizeof(s),0)==-1) { printf("sendfailed%s\n",strerror(errno)); returnEXIT_FAILURE; } close(st); returnEXIT_SUCCESS;}第三章TCP通信
服務(wù)端程序例子。需要包含頭文件#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>intmain(intarg,char*args[]){ intst=socket(AF_INET,SOCK_STREAM,0); inton=1; if(setsockopt(st,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))==-1) { printf("setsockoptfailed%s\n",strerror(errno)); returnEXIT_FAILURE; } structsockaddr_inaddr; memset(&addr,0,sizeof(addr)); addr.sin_family=AF_INET; addr.sin_port=htons(8080); addr.sin_addr.s_addr=htonl(INADDR_ANY); if(bind(st,(structsockaddr*)&addr,sizeof(addr))==-1) { printf("bindfailed%s\n",strerror(errno)); returnEXIT_FAILURE; } if(listen(st,20)==-1) { printf("listenfailed%s\n",strerror(errno)); returnEXIT_FAILURE; } chars[1024]; intclient_st=0; socklen_tlen=0; structsockaddr_inclient_addr; void*p=&client_addr; inti; for(i=0;i<5;i++) { memset(&client_addr,0,sizeof(client_addr)); socklen_tlen=sizeof(client_addr); client_st=accept(st,p,&len); if(client_st==-1) { printf("acceptfailed%s\n",strerror(errno)); returnEXIT_FAILURE; } memset(s,0,sizeof(1024)); if(recv(client_st,s,sizeof(s),0)==-1) { printf("recvfailed%s\n",strerror(errno)); close(client_st); returnEXIT_FAILURE; } printf("revcis%s\n",s); close(client_st); } close(st); returnEXIT_SUCCESS;}第三章TCP通信
intsetsockopt(ints,intlevel,intoptname, constvoid*optval,socklen_toptlen);setsockopt函數(shù)設(shè)置socket常見用法為:inton=1;setsockopt(st,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))由于TCPsocket狀態(tài)TIME_WAIT引起該socket關(guān)閉后約保留2到4分鐘。在此期間bind綁定該端口會(huì)失敗。SO_REUSEADDR指示系統(tǒng)地址可重用。第三章TCP與UDP的對(duì)比
UDP和TCP的對(duì)比。UDP處理的細(xì)節(jié)比TCP少。UDP不能保證消息被傳送到目的地。UDP不能保證數(shù)據(jù)包的傳遞順序。TCP處理UDP不處理的細(xì)節(jié)。TCP是面向連接的協(xié)議。UDP是無連接協(xié)議。TCP保持一個(gè)連接。UDP只是把數(shù)據(jù)發(fā)送出去而已。第三章TCP與UDP的對(duì)比
TCP的優(yōu)點(diǎn)TCP提供以認(rèn)可的方式顯示的創(chuàng)建連接和終止連接。TCP保證可靠的,順序的以及不會(huì)重復(fù)的數(shù)據(jù)傳輸。TCP處理流控制。TCP允許數(shù)據(jù)優(yōu)先。如果數(shù)據(jù)沒有傳送到,TCPsocket會(huì)返回出錯(cuò)提示。TCP通過保持連接并將數(shù)據(jù)塊分成更小的分片來處理大數(shù)據(jù),而無需程序員編碼處理。TCP的缺點(diǎn)TCP需要?jiǎng)?chuàng)建并保持一個(gè)連接,給系統(tǒng)帶來很大開銷。TCP數(shù)據(jù)傳輸效率低。第三章TCP與UDP的對(duì)比
UDP的優(yōu)點(diǎn)UDP不要求保持一個(gè)連接。UDP沒有因接收方?jīng)]有收到數(shù)據(jù)包重傳而帶來開銷。設(shè)計(jì)UDP的目的是用于短應(yīng)用和控制消息。在一個(gè)數(shù)據(jù)包接一個(gè)數(shù)據(jù)包基礎(chǔ)上,UDP要求的網(wǎng)絡(luò)帶寬比TCP小。UDP的缺點(diǎn)程序員必須創(chuàng)建代碼監(jiān)測(cè)數(shù)據(jù)包的正確性,必要時(shí)重傳。程序員必須把大數(shù)據(jù)包分片。第三章TCP與UDP的對(duì)比
選擇使用哪一種協(xié)議?一些消息重要程度不高,或者有規(guī)律重復(fù),可以使用UDP。如果要傳輸一個(gè)重要的數(shù)據(jù),丟失一點(diǎn)就會(huì)破壞整個(gè)數(shù)據(jù),那么需要選擇TCP。telnet,ssh,http等基本都基于TCP。流媒體為了保證很窄的網(wǎng)絡(luò)帶寬來傳送更多的數(shù)據(jù),基本采用UDP。多數(shù)游戲中,丟失來自某個(gè)用戶的狀態(tài)更新可能不會(huì)引起注意,所以采用UDP。設(shè)計(jì)用在局域網(wǎng)的應(yīng)用可以采用UDP,因?yàn)樵诰钟蚓W(wǎng)中丟失數(shù)據(jù)包的可能性很低。ContentsTCP/IP與socketUDP通信TCP通信123非阻塞socket與epoll4小竅門
5第四章非阻塞socket與epoll
阻塞socket。阻塞調(diào)用是指調(diào)用結(jié)果返回之前,當(dāng)前線程會(huì)被掛起。函數(shù)只有在得到結(jié)果之后才會(huì)返回。對(duì)于文件操作read,fread函數(shù)調(diào)用會(huì)將線程阻塞。對(duì)于socket,accept與recv、recvfrom函數(shù)調(diào)用會(huì)將線程阻塞。為了避免整個(gè)進(jìn)程被阻塞后掛起,所以在阻塞模式下,往往需要采用多線程技術(shù)。一個(gè)進(jìn)程中可并發(fā)的線程總數(shù)是有限的,在處理大量客戶端sokcet連接(比如上萬個(gè)clientsocket),通過線程并發(fā)處理socket并不方便,效率也不高。第四章非阻塞socket與epoll
非阻塞socket。非阻塞調(diào)用是指調(diào)用立刻返回。在非阻塞模式下,accept與recv、recvfrom函數(shù)調(diào)用會(huì)立刻返回。在nonblocking狀態(tài)下調(diào)用accept函數(shù),如果沒有客戶端socket連接請(qǐng)求,那么accept函數(shù)返回-1,同時(shí)errno值為EAGAIN或者EWOULDBLOCK,這兩個(gè)宏定義都為整數(shù)11。在nonblocking狀態(tài)下調(diào)用recv、recvfrom函數(shù),如果沒有數(shù)據(jù),函數(shù)返回-1,同時(shí)errno值為11。如果socket已經(jīng)關(guān)閉,函數(shù)返回0。在nonblocking狀態(tài)下對(duì)一個(gè)已經(jīng)關(guān)閉的socket調(diào)用send函數(shù),將引發(fā)一個(gè)SIGPIPE信號(hào),進(jìn)程必須捕捉這個(gè)信號(hào),因?yàn)镾IGPIPE系統(tǒng)默認(rèn)的處理方式是關(guān)閉進(jìn)程。第四章非阻塞socket與epoll
fcntl函數(shù)調(diào)用fcntl函數(shù)可以將文件或者socket描述符設(shè)置為阻塞或者非阻塞狀態(tài)intfcntl(intfd,intcmd,.../*arg*/);參數(shù)fd為要設(shè)置的文件描述符或者socket。參數(shù)cmd,F(xiàn)_GETFL為得到目前狀態(tài),F(xiàn)_SETFL為設(shè)置狀態(tài)。宏定義O_NONBLOCK代表非阻塞,0代表阻塞。返回值為描述符當(dāng)前狀態(tài)。第四章非阻塞socket與epoll
fcntl函數(shù)調(diào)用設(shè)置非阻塞例子intopts=fcntl(st,F_GETFL);if(opts<0){ printf("fcntlfailed%s\n",strerror(errno));}opts=opts|O_NONBLOCK;if(fcntl(st,F_SETFL,opts)<0){ printf("fcntlfailed%s\n",strerror(errno));}第四章非阻塞socket與epoll
fcntl函數(shù)調(diào)用設(shè)置阻塞例子if(fcntl(st,F_SETFL,0)<0){ printf("fcntlfailed%s\n",strerror(errno));}第四章非阻塞socket與epoll
在非阻塞模式下,如何能知道accept與recv有數(shù)據(jù)返回呢?epoll是Linux內(nèi)核為處理大批量文件描述符而作了改進(jìn)的poll,是Linux下多路復(fù)用IO接口select/poll的增強(qiáng)版本,它能顯著提高程序在大量并發(fā)連接中只有少量活躍的情況下的系統(tǒng)CPU利用率。第四章非阻塞socket與epoll
epoll的系統(tǒng)調(diào)用函數(shù):epoll_createepoll_create用來創(chuàng)建一個(gè)epoll文件描述符。epoll_ctlepoll_ctl用來添加/修改/刪除需要偵聽的文件描述符及其事件。epoll_wait。epoll_wait接收發(fā)生在被偵聽的描述符上的,用戶感興趣的IO事件。epoll文件描述符用完后,需要用close關(guān)閉。每次添加/修改/刪除文件描述符都需要調(diào)用epoll_ctl,所以要盡量少地調(diào)用epoll_ctl。第四章非阻塞socket與epoll
epoll_create:intepoll_create(intsize);epoll_create創(chuàng)建一個(gè)epoll的句柄。參數(shù)size指定epoll所支持的最大句柄數(shù)。函數(shù)會(huì)返回一個(gè)新的epoll句柄,之后的所有操作將通過這個(gè)句柄來進(jìn)行操作。在用完句柄之后,需要用close()來關(guān)閉這個(gè)創(chuàng)建出來的epoll句柄。第四章非阻塞socket與epoll
epoll_ctl:intepoll_ctl(intepfd,intop,intfd,structepoll_event*event);參數(shù)epfd是epoll_create()的返回值。參數(shù)op表示動(dòng)作,用三個(gè)宏來表示:EPOLL_CTL_ADD:注冊(cè)新的fd到epfd中;EPOLL_CTL_MOD:修改已經(jīng)注冊(cè)的fd的監(jiān)聽事件;EPOLL_CTL_DEL:從epfd中刪除一個(gè)fd;參數(shù)fd是需要監(jiān)聽的socket描述符。參數(shù)event通知內(nèi)核需要監(jiān)聽什么事件。第四章非阻塞socket與epoll
structepoll_event結(jié)構(gòu)如下:typedefunionepoll_data{void*ptr;intfd;__uint32_tu32;__uint64_tu64;}epoll_data_t;structepoll_event{__uint32_tevents;/*Epollevents*/epoll_data_tdata;/*Userdatavariable*/};第四章非阻塞socket與epoll
events定義:EPOLLIN:表示對(duì)應(yīng)的文件描述符可以讀(包括對(duì)端SOCKET正常關(guān)閉);EPOLLOUT:表示對(duì)應(yīng)的文件描述符可以寫;EPOLLPRI:表示對(duì)應(yīng)的文件描述符有緊急的數(shù)據(jù)可讀(這里應(yīng)該表示有帶外數(shù)據(jù)到來);EPOLLERR:表示對(duì)應(yīng)的文件描述符發(fā)生錯(cuò)誤;EPOLLHUP:表示對(duì)應(yīng)的文件描述符被掛斷;EPOLLET:將EPOLL設(shè)為邊緣觸發(fā)(EdgeTriggered)模式,這是相對(duì)于水平觸發(fā)(LevelTriggered)來說的;EPOLLONESHOT:只監(jiān)聽一次事件,當(dāng)監(jiān)聽完這次事件之后,如果還需要繼續(xù)監(jiān)聽這個(gè)socket的話,需要再次把這個(gè)socket加入到EPOLL隊(duì)列里第四章非阻塞socket與epoll
關(guān)于ET、LT兩種工作模式:LT(leveltriggered)是缺省的工作方式,并且同時(shí)支持block和no-blocksocket.在LT模式中,內(nèi)核通知一個(gè)文件描述符是否就緒了,然后可以對(duì)這個(gè)就緒的fd進(jìn)行IO操作。如果你不作任何操作,內(nèi)核還是會(huì)繼續(xù)通知你的,所以,這種模式編程出錯(cuò)誤可能性要小一點(diǎn)。第四章非阻塞socket與epoll
ET(edge-triggered)是高速工作方式,只支持no-blocksocket。在ET模式下,當(dāng)描述符從未就緒變?yōu)榫途w時(shí),內(nèi)核通過epoll告訴你。ET模式會(huì)假設(shè)你知道文件描述符已經(jīng)就緒,并且不會(huì)再為那個(gè)文件描述符發(fā)送更多的就緒通知,直到你做了某些操作導(dǎo)致那個(gè)文件描述符不再為就緒狀態(tài)了。如果一直不對(duì)這個(gè)fd作IO操作(從而導(dǎo)致它再次變成未就緒),內(nèi)核不會(huì)發(fā)送更多的通知。ET和LT的區(qū)別:LT事件不會(huì)丟棄,而是只要讀buffer里面有數(shù)據(jù)可以讓用戶讀,則不斷的通知你。ET則只在事件發(fā)生之時(shí)通知??梢院唵卫斫鉃長T是水平觸發(fā),而ET則為邊緣觸發(fā)。LT模式只要有事件未處理就會(huì)觸發(fā),而ET則只在高低電平變換時(shí)(即狀態(tài)從1到0或者0到1)觸發(fā)。第四章非阻塞socket與epoll
epoll_wait:intepoll_wait(intepfd,structepoll_event*events,intmaxevents,inttimeout);參數(shù)epfd是epoll_create()的返回值。參數(shù)events是一個(gè)
溫馨提示
- 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. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 四川省簡陽市2022年七年級(jí)《英語》下冊(cè)期中試卷與參考答案
- 成都市新都區(qū)2022年七年級(jí)《地理》上冊(cè)期末試卷與參考答案
- 新版人教PEP版三年級(jí)下冊(cè)英語課件 Unit 3 Part B 第1課時(shí)
- 2025年匙扣卷尺項(xiàng)目投資可行性研究分析報(bào)告
- 大學(xué)生校外住宿申請(qǐng)書
- 山東文化產(chǎn)業(yè)職業(yè)學(xué)院《人力資源管理綜合模擬實(shí)訓(xùn)一》2023-2024學(xué)年第二學(xué)期期末試卷
- 湖州學(xué)院《電路與模擬電子技術(shù)》2023-2024學(xué)年第二學(xué)期期末試卷
- 白水泥行業(yè)國際市場(chǎng)推廣策略研究
- 知識(shí)產(chǎn)權(quán)貫標(biāo)評(píng)審在商業(yè)合作中的重要性
- 農(nóng)產(chǎn)品檢測(cè)服務(wù)合同范本(CMA認(rèn)證機(jī)構(gòu)版)
- 車削成形面和表面修飾加工課件
- 2020外研版九年級(jí)英語上全冊(cè)課文原文及翻譯
- 讀書分享-《教育的情調(diào)》
- 基于振動(dòng)信號(hào)的齒輪故障診斷方法研究
- 義務(wù)教育物理課程標(biāo)準(zhǔn)(2022年版word版)
- 醫(yī)療器械分類目錄2002版
- DB11_T1713-2020 城市綜合管廊工程資料管理規(guī)程
- 氣管套管滑脫急救知識(shí)分享
- 特種設(shè)備自檢自查表
- 省政府審批單獨(dú)選址項(xiàng)目用地市級(jí)審查報(bào)告文本格式
- 往復(fù)式壓縮機(jī)安裝方案
評(píng)論
0/150
提交評(píng)論