天天看點

send的 epoll_wait EPOLLOUT事件 與 MSG_WAITALL參數

1、send 10G的資料,send傳回值不會是10G,而是大約256k,表示你隻成功寫入了256k的資料。接着調用send,send就會傳回EAGAIN,告訴你socket的緩沖區已經滿了,此時無法繼續send。

此時異步程式的正确處理流程是調用epoll_wait,當socket緩沖區中的資料被對方接收之後,緩沖區就會有空閑空間可以繼續接收資料,此時epoll_wait就會傳回這個socket的EPOLLOUT事件,獲得這個事件時,你就可以繼續往socket中寫出資料。

處理EPOLLIN的時候,就可以往sockfd裡寫了(如果需要的話),隻不過這時候,套接字如果是非阻塞的,緩沖區寫滿了,傳回EAGAIN , 然而判斷send(write/sendfile)傳回值發現資料并沒有發完,想要接着把資料發出去,這時候就需要暫時記錄一下現場,包括fd,目前發送到buffer的哪個位元組了,什麼的(可以用一個結構記錄下來). 然後注冊EPOLLOUT事件,等待下一次觸發寫事件.這時要先删除這個fd注冊的寫事件,之後找到fd對應的buffer(這個可以用map儲存起來,以fd做鍵去找對應的結構),從原來的沒有發完的偏移處繼續發資料,發完了就删掉這個map或者将struct裡置空. 沒有發完就再注冊寫事件,記錄這次的位置到哪了.等待下一次觸發寫.

2、不用epoll,隻使用send,send(fd, buff, buffLen, MSG_WAITALL)可以等待所有消息發送完才傳回。

繼續閱讀