TCP/IP Socket網(wǎng)絡(luò)編程心得:
- ET模式下accept
- 考慮這種情況:多個(gè)連接同時(shí)到達(dá),服務(wù)器的 TCP 就緒隊(duì)列瞬間積累多個(gè)就緒連接,由于是邊緣觸發(fā)模式,epoll 只會(huì)通知一次,accept 只處理一個(gè)連接,導(dǎo)致 TCP 就緒隊(duì)列中剩下的連接都得不到處理
- 解決辦法是用 while 循環(huán)抱住 accept 調(diào)用,處理完 TCP 就緒隊(duì)列中的所有連接后再退出循環(huán)。如何知道是否處理完就緒隊(duì)列中的所有連接呢? accept 返回 -1 并且 errno 設(shè)置為 EAGAIN 就表示所有連接都處理完
- 對(duì)端或本端close的處理
- 對(duì)端close, 本端繼續(xù)recv會(huì)返回0,send會(huì)返回-1
- 本端close, 本端繼續(xù)recv會(huì)返回-1,send會(huì)返回-1,errno都是EPIPE
- close(fd)之后,可以通過fd發(fā)送或接收數(shù)據(jù)嗎?如果調(diào)用了send或recv函數(shù)會(huì)報(bào) Broken pipe的錯(cuò)誤嗎?
- 添加signal(SIGPIPE,SIG_IGN); 以免報(bào)Broken Pipe的錯(cuò)誤
- 使用ET和LT的區(qū)別
- LT:水平觸發(fā),效率會(huì)低于ET觸發(fā),尤其在大并發(fā),大流量的情況下。但是LT對(duì)代碼編寫要求比較低,不容易出現(xiàn)問題。LT模式服務(wù)編寫上的表現(xiàn)是:只要有數(shù)據(jù)沒有被獲取,內(nèi)核就不斷通知你,因此不用擔(dān)心事件丟失的情況
- ET:邊緣觸發(fā),效率非常高,在并發(fā),大流量的情況下,會(huì)比LT少很多epoll的系統(tǒng)調(diào)用,因此效率高。但是對(duì)編程要求高,需要細(xì)致的處理每個(gè)請(qǐng)求,否則容易發(fā)生丟失事件的情況
- 采用LT模式下,如果accept調(diào)用有返回就可以馬上建立當(dāng)前這個(gè)連接了,再epoll_wait等待下次通知,和select一樣。 但是對(duì)于ET而言,如果accpet調(diào)用有返回,除了建立當(dāng)前這個(gè)連接外,不能馬上就epoll_wait還需要繼續(xù)循環(huán)accpet,直到返回-1,且errno==EAGAIN
-- 2018/05/26
-- 魔都