目錄答案
深入說明
在 epoll 中的應用 總結
拓展阻塞,事情幹不完就不要回來了!
非阻塞,能幹多少就是多少,趕緊回來!
// 將核心接收緩衝區中的資料 copy 到應用層中使用者的 buffer 中。
int recv(int sockfd, void *buf, size_t len, int flag);
// 將應用層中使用者的 buffer 中的資料 copy 到核心傳送緩衝區中。
int send(int sockfd, void *buf, size_t len, int flag);
1、recv
阻塞模式下,如果核心的接收緩衝區中沒有資料時,該函式就會阻塞。
非阻塞模式下,如果核心的接收緩衝區中沒有資料時,該函式就會返回。
2、send
阻塞模式下,如果傳送緩衝區剩餘的空間小於要傳送的資料的大小,那麼該函式會阻塞。
非阻塞模式下,如果傳送緩衝區剩餘的空間大於要傳送的資料的大小,那麼該函式會返回。
1、水平觸發模式(lt)
在該模式下,recv 和 send 為阻塞和非阻塞,結果是一樣的。
舉 recv 栗子來說,因為在該觸發模式下,只要核心的接收緩衝區中有資料,epoll_wait() 函式都會返回,這就導致了雖然 recv 是阻塞模式的,但是每次呼叫時,核心緩衝區都是有資料的,所以不會導致 recv 阻塞。當然了,當 recv 時是非阻塞的,就更不會造成阻塞情況了。同理,對於 send 也是一樣的。
2、邊沿觸發模式(lt)
在該模式下,recv 和 send 需要為非阻塞模式,不然就會有問題。
還是舉 recv 栗子來說,因為在該模式下,核心的接收緩衝區來資料了,那麼 epoll_wait() 函式就會返回,但是僅僅返回一次,它可不管你是否在該次中是否完全取走了核心接收緩衝區中的資料。
在上述的前提下,recv 需要乙個 while (true) 迴圈,保證將緩衝區中的資料取空。這就產生了乙個問題,因為假如 recv 是阻塞的,那麼當核心緩衝區中沒有資料時,該函式就會阻塞,這是致命的,所以 recv 必須是非阻塞的。
同理,對於 send 也是一樣的。理想情況時,終於有機會向對端傳送資料了,一定要將想發的資料發盡。這就有問題了,如果是阻塞的,如果發到一半,傳送緩衝區滿了,那麼該函式就阻塞了,實際上要避免這種情況,所以要將該 send 設定為非阻塞的。
在水平觸發模式下,recv 和 send 阻塞和非阻塞模式均可。
在邊沿觸發模式下,recv 和 send 必須為非阻塞模式。
1、將socket設定為非阻塞模式的方法。(socket設定為非阻塞的,recv 和 send 要設定為非阻塞的)
int flags = fcntl(sockfd, f_getfl, 0); //獲取檔案的flags值。
fcntl(sockfd, f_setfl, flags | o_nonblock); //設定成非阻塞模式;
int n = recv(fd, pbuff, kbufflen, msg_dontwait);
2、將socket設定為阻塞模式的方法。
int flags = fcntl(sockfd, f_getfl, 0); //獲取檔案的flags值。
fcntl(sockfd, f_setfl, flags | ~o_nonblock); //設定成阻塞模式;
int n = recv(fd, pbuff, kbufflen, 0); // flag = 0,預設是阻塞的。
(saw:game over!)
阻塞和非阻塞
在 windows 下的 socket 程式設計有兩個程式設計模型,阻塞和非阻塞。有時,他們也被叫做同步 阻 塞 和非同步 非阻塞 在 unix 中只支援阻塞模型。阻塞 indy 使用阻塞 socket 呼叫。阻塞呼叫很像乙個檔案的讀寫。當你讀資料或者寫資料時,直 到操作完成,函式才會返回。不同的是...
阻塞和非阻塞
在 windows 下的 socket 程式設計有兩個程式設計模型,阻塞和非阻塞。有時,他們也被叫做同步 阻 塞 和非同步 非阻塞 在 unix 中只支援阻塞模型。阻塞 indy 使用阻塞 socket 呼叫。阻塞呼叫很像乙個檔案的讀寫。當你讀資料或者寫資料時,直 到操作完成,函式才會返回。不同的是...
關於send函式在阻塞模式和非阻塞模式下的區別
在阻塞模式下,send函式的過程是將應用程式請求傳送的資料拷貝到傳送快取中傳送並得到確認後再返回.但由於傳送快取的存在,表現為 如果傳送快取大小比請求傳送的大小要大,那麼send函式立即返回,同時向網路中傳送資料 否則,send向網路傳送快取中不能容納的那部分資料,並等待對端確認後再返回 接收端只要...