日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于epoll 水平触发在udp套接字上不生效问题的原因

發布時間:2025/4/5 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于epoll 水平触发在udp套接字上不生效问题的原因 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

相關知識點簡介: epoll有兩個模式可以設置,一個是水平模式(level-triggered),另一個是邊緣模式(edge-triggered), 區別就是水平模式可以帶來事件的重復觸發,而邊緣模式只觸發一次。舉個栗子,當epoll監聽的描述符發生可讀事件時,比方說收到了別人發來的10個字節數據,你只讀了一個字節,如果是水平觸發,那么epoll將一直觸發直到剩下那9個字節讀完,而邊緣觸發呢,就是收到了一個讀事件,你自己去讀吧,讀多少算多少,而epolll只觸發一次。

而我在實際測試epoll監聽udp套接字的時候,使用默認的水平觸發去監聽讀事件,每次只讀取一個字節,按道理收到多個字節epoll應該觸發(trigger)多次才對,結果它只觸發了一次,如圖:


程序啟動后監聽3500端口,使用網絡調試助手發3個字節到監聽地址,只讀取一個,結果顯示epoll觸發一次后就hang住

代碼這樣寫的:

while(1) {fds = epoll_wait(efd, epoll_events_ptr, 2, -1); //阻塞for (i = 0; i<fds; i++){ if (epoll_events_ptr[i].events & EPOLLIN){ ret = read(fd1, buffer, 1);if(ret != -1)log("recv msg : %s \n", buffer);} memset(buffer, 0, BUFFER_SIZE);} }

同樣情況下,如果監聽的是標準輸入的話,epoll觸發了多次,如下圖,代碼就不貼了


兩個例子流程基本一樣,除了一個監聽udp套接字,一個監聽標準輸入(STDIN_FILENO)

最后在stackoverflow上有大神解答說UDP套接字是以報文為單位的,如果一次沒有讀取完成,剩余數據會被丟棄,這解釋了為什么epoll只觸發了一次,因為在讀取一個字節的時候,剩余兩個字節被丟棄了。這和面向字節流的TCP套接字不同。

stackoverflow上的問題鏈接:

https://stackoverflow.com/questions/50938689/epoll-eventsepolllt-only-triggered-once-on-udp-socket/50939267#50939267

創建了一個linux應用&內核相關開發到討論群:745510310 歡迎有興趣的同學加入

總結

以上是生活随笔為你收集整理的关于epoll 水平触发在udp套接字上不生效问题的原因的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。