關於epoll的示例

2021-07-09 02:30:41 字數 3419 閱讀 4364

下午研究了一下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. 下面是客戶端實驗**

1

int2 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事件發生...