Epoll 連線無響應或響應時間過長
阿新 • • 發佈:2019-02-04
Epoll有兩種模式,LT模式 與 ET模式。預設情況下是LT模式,由於ET模式在高併發,高流量的情況下,處理效率會高於ET模式,所以也就採用了ET模式。
伺服器一直執行良好,跑幾千機器人也沒有什麼問題。但突然之間發現,機器人在反覆掉線上線的測試後,會出現一種情況:伺服器端會再也收不到客戶端的連線事件,或者這個連線事件響應會非常慢,而已連線成功的fd讀寫資料是沒有任何問題的。
主要的原因還是因為ET模組的程式碼編寫要求比較高,LT模式就像汽車的自動檔,你只要掛上檔,就能把速度搞上去。而ET模式有點像汽車的手動檔,任何時候變速都是需要你自己操作的。LT是條件觸發,只要滿足條件,是一直觸發,直到你把它處理完成。而ET有點型別是事件觸發,發生了某個事件的時候,他只觸發一次,如果這一次你沒能在邏輯裡寫處理好,那就不會再觸發了,那這個事件的處理就被丟失。
所以我的問題應該還是沒能把ET模式用好,最後的解決辦法大概如下,還原回了預設的方式:
bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr));
listen(listenfd, LISTENQ);
ev.data.fd=listenfd;
//ev.events=EPOLLIN|EPOLLET;
ev.events=EPOLLIN;//監聽的FD 用預設的EPOLLLT模式
if(events[i].data.fd==listenfd) //如果新監測到一個SOCKET使用者連線到了繫結的SOCKET埠,建立新的連線。 { connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen); if(connfd<0){ perror("connfd<0"); return (1); } setnonblocking(connfd); ev.data.fd=connfd; //ev.events=EPOLLIN | EPOLLET; ev.events=EPOLLIN;//這裡也用預設的EPOLLLT模式 epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev); }