關於send函式在阻塞模式和非阻塞模式下的區別

2021-09-25 18:07:40 字數 1038 閱讀 4775

在阻塞模式下,send函式的過程是將應用程式請求傳送的資料拷貝到傳送快取中傳送並得到確認後再返回.但由於傳送快取的存在,表現為:如果傳送快取大小比請求傳送的大小要大,那麼send函式立即返回,同時向網路中傳送資料;否則,send向網路傳送快取中不能容納的那部分資料,並等待對端確認後再返回(接收端只要將資料收到接收快取中,就會確認,並不一定要等待應用程式呼叫recv);

在非阻塞模式下,send函式的過程僅僅是將資料拷貝到協議棧的快取區而已,如果快取區可用空間不夠,則盡能力的拷貝,返回成功拷貝的大小;如快取區可用空間為0,則返回-1,同時設定errno為11(eagain).

當客戶通過socket提供的send函式傳送大的資料報時,就可能返回乙個eggain的錯誤。該錯誤產生的原因是由於send函式中的size變數大小超過了tcp_sendspace的值。tcp_sendspace定義了應用在呼叫send之前能夠在kernel中快取的資料量。當應用程式在socket中設定了o_ndelay或者o_nonblock屬性後,如果傳送快取被佔滿,send就會返回eagain的錯誤。

為了消除該錯誤,有三種方法可以選擇:

1).調大tcp_sendspace,使之大於send中的size引數

---no -p -otcp_sendspace=65536

2).在呼叫send前,在setsockopt函式中為sndbuf設定更大的值

intopt=so_reuseaddr;

setsockopt(tcp_client_sock,sol_socket,so_reuseaddr,&opt,sizeof(opt));

opt = 256*1024;//512k

int optlen = sizeof(int);

setsockopt(tcp_client_sock,sol_socket,so_sndbuf,&opt,sizeof(int));

getsockopt(tcp_client_sock,sol_socket,so_sndbuf,&opt,&optlen); 

3).使用write替代send,因為write沒有設定o_ndelay或者o_nonblock

recv 和 send 阻塞和非阻塞的區別

目錄答案 深入說明 在 epoll 中的應用 總結 拓展阻塞,事情幹不完就不要回來了!非阻塞,能幹多少就是多少,趕緊回來!將核心接收緩衝區中的資料 copy 到應用層中使用者的 buffer 中。int recv int sockfd,void buf,size t len,int flag 將應用...

阻塞模式和非阻塞模式

好文得轉 何為阻塞?在以上過程中若連線還沒到來,那麼 accept 會阻塞 程式執行到這裡不得不掛起,cpu 轉而執行其他執行緒。在以上過程中若資料還沒準備好,read 會一樣也會阻塞。阻塞式網路 io 的特點 多執行緒處理多個連線。每個執行緒擁有自己的棧空間並且占用一些 cpu 時間。每個執行緒遇...

Socket 阻塞模式和非阻塞模式

阻塞i o模型 簡介 程序會 一直阻塞 直到資料拷貝 完成 應用程式呼叫乙個io函式,導致應用程式阻塞,等待資料準備好。如果資料沒有準備好,一直等待 資料準備好了,從核心拷貝到使用者空間,io函式返回成功指示。阻塞i o模型圖 在呼叫recv recvfrom 函式時,發生在核心中等待資料和複製資料...