关于epoll 水平触发在udp套接字上不生效问题的原因
相關(guān)知識點簡介: epoll有兩個模式可以設(shè)置,一個是水平模式(level-triggered),另一個是邊緣模式(edge-triggered), 區(qū)別就是水平模式可以帶來事件的重復(fù)觸發(fā),而邊緣模式只觸發(fā)一次。舉個栗子,當(dāng)epoll監(jiān)聽的描述符發(fā)生可讀事件時,比方說收到了別人發(fā)來的10個字節(jié)數(shù)據(jù),你只讀了一個字節(jié),如果是水平觸發(fā),那么epoll將一直觸發(fā)直到剩下那9個字節(jié)讀完,而邊緣觸發(fā)呢,就是收到了一個讀事件,你自己去讀吧,讀多少算多少,而epolll只觸發(fā)一次。
而我在實際測試epoll監(jiān)聽udp套接字的時候,使用默認(rèn)的水平觸發(fā)去監(jiān)聽讀事件,每次只讀取一個字節(jié),按道理收到多個字節(jié)epoll應(yīng)該觸發(fā)(trigger)多次才對,結(jié)果它只觸發(fā)了一次,如圖:
程序啟動后監(jiān)聽3500端口,使用網(wǎng)絡(luò)調(diào)試助手發(fā)3個字節(jié)到監(jiān)聽地址,只讀取一個,結(jié)果顯示epoll觸發(fā)一次后就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);} }同樣情況下,如果監(jiān)聽的是標(biāo)準(zhǔn)輸入的話,epoll觸發(fā)了多次,如下圖,代碼就不貼了
兩個例子流程基本一樣,除了一個監(jiān)聽udp套接字,一個監(jiān)聽標(biāo)準(zhǔn)輸入(STDIN_FILENO)
最后在stackoverflow上有大神解答說UDP套接字是以報文為單位的,如果一次沒有讀取完成,剩余數(shù)據(jù)會被丟棄,這解釋了為什么epoll只觸發(fā)了一次,因為在讀取一個字節(jié)的時候,剩余兩個字節(jié)被丟棄了。這和面向字節(jié)流的TCP套接字不同。
stackoverflow上的問題鏈接:
https://stackoverflow.com/questions/50938689/epoll-eventsepolllt-only-triggered-once-on-udp-socket/50939267#50939267
創(chuàng)建了一個linux應(yīng)用&內(nèi)核相關(guān)開發(fā)到討論群:745510310 歡迎有興趣的同學(xué)加入
總結(jié)
以上是生活随笔為你收集整理的关于epoll 水平触发在udp套接字上不生效问题的原因的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: fx53v怎么做系统 ASUS fx53
- 下一篇: 渭南国防生学校有哪些