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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

epoll 的accept , read, write

發布時間:2025/5/22 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 epoll 的accept , read, write 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://www.ccvita.com/515.html

在一個非阻塞(fcntl)的socket上調用read/write函數, 返回EAGAIN或者EWOULDBLOCK(注: EAGAIN就是EWOULDBLOCK)

這個錯誤表示資源暫時不夠, 可能read時, 讀緩沖區沒有數據, 或者, write時,寫緩沖區滿了. ?(此處讀寫緩沖區指的是socket的緩沖區,而不是read或write調用形參中的buffer)

遇到這種情況, 如果是阻塞socket, read/write就要阻塞掉.而如果是非阻塞socket, read/write立即返回-1, 同?時errno設置為EAGAIN.所以, 對于阻塞socket, read/write返回-1代表網絡出錯了.但對于非阻塞socket, read/write返回-1不一定網絡真的出錯了.可能是Resource temporarily unavailable. 這時你應該再試, 直到Resource available.

綜上, 對于non-blocking的socket, ?正確的讀寫操作為:

讀: 忽略掉errno = EAGAIN的錯誤, 下次繼續讀 

寫:?忽略掉errno = EAGAIN的錯誤, 下次繼續寫 

對于select和epoll的LT模式, 這種讀寫方式是沒有問題的. 但對于epoll的ET模式, 這種方式還有漏洞.

epoll的兩種模式 LT 和 ET

二者的差異在于 level-trigger 模式下只要某個 socket 處于 readable/writable 狀態,無論什么時候調用epoll_wait 都會返回該 socket;而 edge-trigger 模式下只有某個 socket 從 unreadable 變為 readable 或從unwritable 變為 writable 時,epoll_wait 才會返回該 socket。

從socket讀數據:

往socket寫數據:

所以, 在epoll的ET模式下, 正確的讀寫方式為:

讀: 只要可讀, 就一直讀, 直到返回0, 或者 errno = EAGAIN

寫: 只要可寫, 就一直寫, 直到數據發送完, 或者 errno = EAGAIN

正確的讀:

n = 0; while ((nread = read(fd, buf + n, BUFSIZ-1)) > 0) { n += nread; } if (nread == -1 && errno != EAGAIN) { perror("read error"); }

正確的寫:

int nwrite, data_size = strlen(buf); n = data_size; while (n > 0) { nwrite = write(fd, buf + data_size - n, n); if (nwrite < n) { if (nwrite == -1 && errno != EAGAIN) { perror("write error"); } break; } n -= nwrite; }

我的理解:LT模式下,read、write不需要while循環了,即使這次系統調用沒有處理完所有數據,下次調用epoll_wait時也會返回該就緒事件(上述write相關代碼感覺不對)

讀函數read??
ssize_t?read(int?fd,void?*buf,size_t?nbyte)? read函數是負責從fd中讀取內容.成功時,read返回實際所讀的字節數,如果返回的值是0,表示已經讀到文件的結束了. 小于0表示出現了錯誤.如果錯誤為EINTR說明讀是由中斷引起的,?如果是ECONNREST表示網絡連接出了問題. 寫函數write??
ssize_t?write(int?fd,const?void?*buf,size_t?nbytes)?
write函數將buf中的nbytes字節內容寫入文件描述符fd.成功時返回寫的字節數.失敗時返回-1.?并設置errno變量.?在網絡程序中,當我們向套接字文件描述符寫時有倆種可能.??
1)write的返回值大于0,表示寫了部分或者是全部的數據.??
2)返回的值小于0,此時出現了錯誤.我們要根據錯誤類型來處理.? 如果錯誤為EINTR表示在寫的時候出現了中斷錯誤.??
如果為EPIPE表示網絡連接出現了問題(對方已經關閉了連接)

正確的accept,accept 要考慮 2 個問題

(1) 阻塞模式 accept 存在的問題

accept每次都是從已經完成三次握手的tcp隊列中取出一個連接

考慮這種情況: TCP 連接被客戶端夭折,即在服務器調用 accept 之前,客戶端主動發送 RST 終止連接,導致剛剛建立的連接從就緒隊列中移出,如果套接字被設置成阻塞模式,服務器就會一直阻塞在 accept 調用上(即此時沒有客戶端連接給accept),直到其他某個客戶建立一個新的連接為止(即accept接受新的連接,返回)。但是在此期間,服務器單純地阻塞在accept 調用上,就緒隊列中的其他描述符都得不到處理(我的理解:其他fd讀寫事件就緒但得不到處理).

解決辦法是把監聽套接口設置為非阻塞,當客戶在服務器調用 accept 之前中止某個連接時,accept 調用可以立即返回 -1, 這時源自 Berkeley 的實現會在內核中處理該事件,并不會將該事件通知給 epoll,而其他實現把 errno 設置為 ECONNABORTED 或者 EPROTO 錯誤,我們應該忽略這兩個錯誤。

(2) ET 模式下 accept 存在的問題

考慮這種情況:多個連接同時到達,服務器的 TCP 就緒隊列瞬間積累多個就緒連接,由于是邊緣觸發模式,epoll 只會通知一次,accept 只處理一個連接,導致 TCP 就緒隊列中剩下的連接都得不到處理。

解決辦法是用 while 循環抱住 accept 調用,處理完 TCP 就緒隊列中的所有連接后再退出循環。如何知道是否處理完就緒隊列中的所有連接呢? accept??返回 -1 并且 errno 設置為 EAGAIN 就表示所有連接都處理完。

綜合以上兩種情況,服務器應該使用非阻塞地 accept, accept 在 ET 模式下 的正確使用方式為:

while ((conn_sock = accept(listenfd,(struct sockaddr *) &remote, (size_t *)&addrlen)) > 0) { handle_client(conn_sock); } if (conn_sock == -1) { if (errno != EAGAIN && errno != ECONNABORTED && errno != EPROTO && errno != EINTR) perror("accept"); }

我的總結:當epoll在ET模式下,read、write、accept操作都在while循環中執行,使得所有數據或者連接都處理完,因為ET模式下,epoll_wait只返回一次

?

一道騰訊后臺開發的面試題

使用Linux epoll模型,水平觸發模式,當socket可寫時,會不停的觸發 socket 可寫的事件,如何處理?

第一種最普遍的方式:

需要向 socket 寫數據的時候才把 socket 加入 epoll ,等待可寫事件。接受到可寫事件后,調用 write 或者 send 發送數據。當所有數據都寫完后,把 socket 移出 epoll。

這種方式的缺點是,即使發送很少的數據,也要把 socket 加入 epoll,寫完后在移出 epoll,有一定操作代價。

一種改進的方式:

開始不把 socket 加入 epoll,需要向 socket 寫數據的時候,直接調用 write 或者 send 發送數據。如果返回 EAGAIN,把 socket 加入 epoll,在 epoll 的驅動下寫數據,全部數據發送完畢后,再移出 epoll。

這種方式的優點是:數據不多的時候可以避免 epoll 的事件處理,提高效率。

轉載于:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/5655984.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的epoll 的accept , read, write的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 日韩一区二区免费在线观看 | 91精品欧美一区二区三区 | 粉嫩av | 黄色片在线免费观看视频 | 高清日韩 | 国产资源av | 婷婷狠狠操| 欧美区二区三区 | 亚洲一区二区免费电影 | 欧美做爰全过程免费看 | 综合久久影院 | 久久99久久99精品免视看婷婷 | 国产人免费人成免费视频 | 亚洲天堂日本 | 99精品国产成人一区二区 | 森泽佳奈中文字幕 | 俄罗斯毛片基地 | 色狠狠久久av大岛优香 | 麻豆视频二区 | 亚洲免费视频播放 | 国内精品视频 | 92国产精品 | 户外露出一区二区三区 | 白丝女仆被免费网站 | 91青青草| 在线综合视频 | 久久久久久一区 | 久久久久国产精品一区 | 操女网站 | 九九五月天 | 91片黄在线观 | 女同性做爰全过程 | 海角国产乱辈乱精品视频 | 久久一区二区电影 | 欧美性生交大片免费看 | 黄色av免费观看 | 成人av在线网址 | 区一区二在线观看 | 国产一级二级三级 | 中文在线中文资源 | 亚洲日本精品视频 | 操操操免费视频 | 熟女熟妇伦久久影院毛片一区二区 | 骚婷婷 | 亚洲最大福利视频 | www黄色com| 国产另类在线 | 91蝌蚪九色 | 日本少妇性生活 | 美脚の诱脚舐め脚 | 亚洲一区二区成人 | 巨大胸大乳奶电影 | 日本裸体网站 | 中文字幕精品亚洲 | 美女视频黄的免费 | 99视频网 | 国产日日夜夜 | 特黄av| 草草国产 | 国产一区二区三区四区精 | 葵司免费一区二区三区四区五区 | 福利所第一导航 | 亚洲乱码国产乱码精品天美传媒 | 性淫影院 | 人善交videos欧美3d动漫 | 男人都懂的网站 | 国产馆视频 | 影音av资源| 成人性生活免费视频 | 久久人妖| 中文字幕高清在线 | 自宅警备员在线观看 | 美女干b视频 | 69视频在线播放 | 成人乱码一区二区三区av | 国产麻豆剧果冻传媒白晶晶 | 肉嫁高柳在线 | 美女脱了裤子让男人捅 | 国产精品欧美一区二区 | 国产美女精品一区二区三区 | 艳母动漫在线播放 | 欧美蜜臀| 性视频久久 | 91欧美在线 | 欧美成人秋霞久久aa片 | 51成人 | 中国a级大片 | 超级黄色录像 | 成人一二三 | 国产毛片aaa | 日韩亚洲欧美综合 | aaaaaa毛片| 在线一区二区三区视频 | 日韩伦理中文字幕 | 免费看av的网址 | 日韩电影一区二区三区四区 | 黄色欧美网站 | 精品少妇久久久 | 影音先锋欧美资源 |