下午研究了一下epoll,參考了以下的部落格綜合寫了乙個例子。
這篇文章中有一些和我從man上面查到的不相符合的地方,特此指出。
1)關於epoll_create
這個函式的size引數已經器用。更推薦使用的是epoll_create1(0)來代替普通的用法。另外epoll_create1(epollcloexec)表示生成的epoll fd具有「執行後關閉」特性。
2) epoll_ctl
這個函式在指定epoll_ctl_del時,為了與linux核心2.6.9之前相相容,還是要讓最後的引數指向乙個非null變數。
另外,events.epolloneshot確實表示只監聽一次事件,但是當我們監聽完這次事件之後,如果還需要繼續監聽這個fd的話,只需要使用epoll_ctl_mod修改event。
3) 關於例項**
例項**我執行了一下,感覺有點問題。後來參考了這篇文章(的說法,發現修改之後就可以實行了。關鍵點有這麼幾點,
1. epollet其實比epolllt高階,所以優先用。
2. 用epollet的時候,按照man的**,是必須要使用非阻塞fd,另外,必須要考慮eagain。
先上伺服器**
1 #include 2 #include 3 #include 4 #include in.h>注意以下幾點:5 #include 6 #include 7 #include 8 #include 9 #include 10 #include
1112
using
namespace
std;
1314
#define maxline 5
15#define open_max 100
16#define listenq 20
17#define serv_port 5000
18#define inftim 1000
1920
void setnonblocking(int
sock)
2129 opts = opts|o_nonblock;
30if(fcntl(sock,f_setfl,opts)<0)31
35}3637
void closeanddisable(int
sockid, epoll_event ee)
3842
43int
main()
44104
105106
char *str =inet_ntoa(clientaddr.sin_addr);
107 cout << "
accapt a connection from
"<< str <
108//
設定用於讀操作的檔案描述符
109110
setnonblocking(connfd);
111 ev.data.fd=connfd;
112//
設定用於注測的讀操作事件
113114 ev.events=epollin |epollet;
115//
ev.events=epollin;
116117
//註冊ev
118 epoll_ctl(epfd,epoll_ctl_add,connfd,&ev);
119}
120else
if(events[i].events & epollin)//
如果是已經連線的使用者,並且收到資料,那麼進行讀入。
121143
else
if (errno ==econnreset)
144150
else
if (errno ==eintr)
151155
else
156162
}163
else
if( recvnum == 0
)164
170171
//recvnum > 0
172 count +=recvnum;
173if ( recvnum ==maxline)
174177
else
//0 < recvnum < maxline
178183
}184
185if (breadok == true
)186
201}
202else
if(events[i].events & epollout) //
如果有資料傳送
203225
else
if(errno ==econnreset)
226232
else
if (errno ==eintr)
233237
else
238241
}242
243if (writenlen == 0
)244
250251
//以下的情況是writenlen > 0
252 count +=writenlen;
253if (writenlen ==maxline)
254258
else
//0 < writenlen < maxline
259264
}265
266if (bwritten == true
)267
276}
277}
278}
279return0;
280 }
1. #14設定為5是故意的,為了測試後續的輸入和輸出
2. 整個伺服器的功能是先讀取字串,然後向對方寫內容。
3. #110處設定通訊socket為非阻塞。
4. 注意#130~#183的讀乾淨緩衝區的read。
5. 注意#213~#264的完全寫完所需要傳送內容的write。
6. 關於epollet,epoll_wait只有在socket狀態發生變化的時候才會返回。所以要對fd進行迴圈accept,read, write;知直到socket的緩衝區空(read, accept)或者填滿(write)為止。
7. 下面是客戶端實驗**
1int2 main(int argc, char **argv)338
else
39break;40
}41 printf("
%s\n
", recvline);42}
43 exit(0
);44 }
Epoll 使用示例
by fireworks foxmail.com 所謂邊沿觸發 將呼叫 epoll wait 期間的事件進行了合併,因此事件數量較多時,邊沿觸發才顯出優勢 使用udp時,如果 read 時緩衝區小於包長時,其結果是依賴於實現的,可能會導致epoll wait出錯 其他相關的背景知識,可以在網上輕鬆獲...
關於epoll的小應用
epoll用到的所有函式都是在標頭檔案sys epoll.h中宣告的,下面簡要說明所用到的資料結構和函式 所用到的資料結構 typedef union epoll data epoll data t struct epoll event 結構體epoll event 被用於註冊所感興趣的事件和回傳所...
關於epoll檢測非同步連線的方法
因為epoll本身沒有明確提出當非同步connect成功之後會返回什麼樣的訊號,通過測試有如下結果 1,當本地還沒呼叫connect函式,卻將套接字送交epoll檢測,epoll會產生一次 epollout epollhup,也就是產生乙個值為0x14的events.2,當本地connect事件發生...