1. 程式人生 > >阻塞模式和非阻塞模式下send、sendto、recv、recvfrom的表現

阻塞模式和非阻塞模式下send、sendto、recv、recvfrom的表現

首先socket在預設情況下是阻塞狀態的(未指非同步操作以及其它一些特殊用途下,直接預設為非阻塞),這就使得傳送以及接收操作處於阻塞的狀態,即呼叫不會立即返回,而是進入睡眠等待操作完成。下面把討論點分為傳送以及接收。

  一.傳送選用send(這裡特指TCP)以及sendto(這裡特指UDP)來描述 

首先需要說明的是,不管阻塞還是非阻塞,在傳送時都會將資料從應用緩衝區拷貝到核心緩衝區(SO_RCVBUF選項宣告,除非緩衝區大小為0)。

1、在阻塞模式下send操作將會等待所有資料均被拷貝到傳送緩衝區後才會返回。

 如果當前傳送緩衝總大小為8192,已經拷貝到緩衝的資料為8000,那剩餘的大小為192,現在需要傳送2000位元組資料,那阻塞傳送就會等待緩衝區足夠把所有2000位元組資料拷貝進去,如第一次拷貝進192位元組,當緩衝區成功傳送出1808位元組後,再把應用緩衝區剩餘的1808位元組拷貝到核心緩衝,而後send操作返回成功傳送位元組數。

    從上面的過程不難看出,阻塞的send操作返回的傳送大小,必然是你引數中的傳送長度的大小。

2、在阻塞模式下的sendto操作不會阻塞。

    關於這一點的原因在於:UDP並沒有真正的傳送緩衝區,它所做的只是將應用緩衝區拷貝給下層協議棧,在此過程中加上UDP頭,IP頭,所以實際不存在阻塞。

3、在非阻塞模式下send操作呼叫會立即返回。

    關於立即返回大家都不會有異議。還是拿阻塞send的那個例子來看,當緩衝區只有192位元組,但是卻需要傳送2000位元組時,此時呼叫立即返回,並得到返回值為192。從中可以看到,非阻塞send僅僅是儘自己的能力向緩衝區拷貝儘可能多的資料,因此在非阻塞下send才有可能返回比你引數中的傳送長度小的值。

    如果緩衝區沒有任何空間時呢?這時肯定也是立即返回,但是你會得到WSAEWOULDBLOCK/E WOULDBLOCK 的錯誤,此時表示你無法拷貝任何資料到緩衝區,你最好休息一下再嘗試傳送。

4、在非阻塞模式下sendto操作 不會阻塞(與阻塞一致,不作說明)。 

  二.接收選用recv(這裡特指TCP)以及recvfrom(這裡特指UDP)來描述

    在阻塞模式下recv,recvfrom操作將會阻塞 到緩衝區裡有至少一個位元組(TCP)或者一個完整UDP資料報才返回。

    在沒有資料到來時,對它們的呼叫都將處於睡眠狀態,不會返回。 

    在非阻塞模式下recv,recvfrom操作將會立即返回。

    如果緩衝區有任何一個位元組資料(TCP)或者一個完整UDP資料報,它們將會返回接收到的資料大小。而如果沒有任何資料則返回錯誤 WSAEWOULDBLOCK/E WOULDBLOCK。

相關推薦

阻塞模式阻塞模式sendsendtorecvrecvfrom表現

首先socket在預設情況下是阻塞狀態的(未指非同步操作以及其它一些特殊用途下,直接預設為非阻塞),這就使得傳送以及接收操作處於阻塞的狀態,即呼叫不會立即返回,而是進入睡眠等待操作完成。下面把討論點分為傳送以及接收。  一.傳送選用send(這裡特指TCP)以及sendto(

Socket的阻塞模式阻塞模式

來源:http://blog.csdn.net/VCSockets/阻塞模式   Windows套接字在阻塞和非阻塞兩種模式下執行I/O操作。在阻塞模式下,在I/O操作完成前,執行的操作函式一直等候而不會立即返回,該函式所在的執行緒會阻塞在這裡。相反,在非阻塞模式下,套接字函式會立即返回,而不管I/O是否完

Oracle歸檔模式歸檔模式的區別

tar pos copy 文件組 歸檔模式 rom 冷備 使用 允許 一。查看oracle數據庫是否為歸檔模式:Sql代碼1.select name,log_mode from v$database; NAME LOG_MODE ----

阻塞IO阻塞IO

如果 tcp協議 必須 每一個 協議 報文 緩沖區 緩沖 可讀的 1 TCP協議 每一個TCP通信的的socket的內核裏面都會有一個發送緩沖區和接收緩沖區 發送端 : send 報文 -- TCP發送緩沖區 -- 接收端 :TCP接收緩沖區 -- receive TCP報

什麽是阻塞阻塞io流?

程序 保存 方法 函數 連接數 簡單 列表 效率 意思 阻塞IO:socket 的阻塞模式意味著必須要做完IO 操作(包括錯誤)才會返回。 非阻塞IO:非阻塞模式下無論操作是否完成都會立刻返回,需要通過其他方式來判斷具體操作是否成功。 兩者區別: 所

js中的嚴格模式嚴格模式的比較

全局變量 賦值 cat 範圍 瀏覽器 進制 函數調用 使用 err 前言 es5的嚴格模式是采用具有限制性JavaScript變體的一種方式,從而使代碼顯示地脫離‘懶散模式/非嚴格模式’ 嚴格模式 嚴格模式通過拋出錯誤來消除一些原有靜默錯誤 嚴格模式修復了一些導致Java

貪婪模式貪婪模式

1.什麼是正則表示式的貪婪與非貪婪匹配 如:String str=“abcaxc”; Patter p=“ab.*c”; 貪婪匹配:正則表示式一般趨向於最大長度匹配,也就是所謂的貪婪匹配。如上面使用模式p匹配字串str,結果就是匹配到:abcaxc(ab.*c)。 非貪婪匹配

同步佇列(阻塞佇列阻塞佇列)

在併發程式設計中,很多情況下需要使用執行緒安全的佇列。而實現執行緒安全的佇列有兩種實現方式 1、使用阻塞演算法:使用阻塞演算法的佇列可以用一個鎖(入隊和出隊使用同一把鎖)或兩個鎖(入隊和出隊用不同的鎖)等方式來實現(基於鎖的演算法會帶來一些活躍度失敗的風險。如果執行緒在持有

同步IO非同步IO阻塞IO阻塞IO

1、IO        IO (Input/Output,輸入/輸出)即資料的讀取(接收)或寫入(傳送)操作,通常使用者程序中的一個完整IO分為兩階段:使用者程序空

STM32 多通道ADC採集詳解(DMA模式DMA模式

ADC相關問題: 1.採集到的值如何轉化計算?   在STM32系列晶片大都是12位只有少部分是16位的,如:F373晶片。   12位解析度意味著我們採集電壓的精度可以達到:Vref / 4096。    採集電壓= Vref * ADC_DR / 4096;  

js中嚴格模式嚴格模式的區別

1、在嚴格模式中禁止使用with語句。 2、在嚴格模式中,所有的變數都要先宣告,如果給一個未宣告的變數、函式、函式引數、catch從句引數或全域性物件的屬性賦值,將會丟擲一個引用錯誤(在非嚴格模式中,這種隱式宣告的全域性變數的方法是給全域性物件新新增一個新屬性)。 3、在嚴格模式

圖解阻塞io阻塞io及多路複用機制

文章目錄IOTCP通訊阻塞IO非阻塞IO IO 即Input Stream與Output Stream TCP通訊 在介紹IO之前我們首先我們先了解一下TCP協議,對於TCP通訊來說,每個TCP的scoket核心裡面都有一個接受與傳送緩衝區。 資料在應用層的s

Python正則表示式中的貪心模式貪心模式

宣告:最近發現有人利用我在百度雲盤裡免費分享的127課Python視訊盈利,並聲稱獲得我的授權。

阻塞IO阻塞IO的區別(轉載)

轉載地址: http://blog.sina.com.cn/s/blog_a46817ff0101g0gv.html http://blog.csdn.net/nodeathphoenix/article/details/30389317 有很多人把阻塞認為是同步

什麼是阻塞阻塞io流?

Java中的阻塞和非阻塞IO包各自的優劣思考 NIO 設計背後的基石:反應器模式,用於事件多路分離和分派的體系結構模式。 反應器(Reactor):用於事件多路分離和分派的體系結構模式 通常的,對一個檔案描述符指定的檔案或裝置, 有兩種工作方式: 阻塞 與非阻塞 。所謂阻塞方

唯快不破:TCP網路程式設計--阻塞accept阻塞connect

非阻塞accept 當一個已完成的連線準備好被accept的時候,select會把監聽socket標記為可讀。因此,如果用select等待外來的連線時,應該不需要把監聽socket設定為非阻塞模式,因為如果select告訴我們連線已經就緒,accept就不應該被阻塞。不過這樣做的時候有一個BUG:當客戶端在

阻塞Socket阻塞Socket

什麼是阻塞socket,什麼是非阻塞socket。對於這個問題,我們要先弄清什麼是阻塞/非阻塞。阻塞與非阻塞是對一個檔案描述符指定的檔案或裝置的兩種工作方式。 阻塞的意思是指,當試圖對該檔案描述符進行讀寫時,如果當時沒有東西可讀或者暫時不可寫,程式就進入等待狀態,直到有東

js中正則表示式的貪婪模式貪婪模式

在講貪婪模式和惰性模式之前,先回顧一下JS正則基礎: 寫法基礎: ①不需要雙引號,直接用//包含 => /wehfwue123123/.test(); ②反斜槓\表示轉義 =>/\.jpg$/ ③用法基礎:.test(str); 語法: ①錨點類 /^a/=&g

Python正則表示式的貪婪模式貪婪模式

貪婪模式是把所有匹配的獲取到,非貪婪模式只取到第一個匹配到的字串,在python中findall和match的區別。 http://blog.csdn.net/qq_33447462/article/details/51485900 .*與.*?的區別:

關於sendsendto阻塞阻塞模式的底層細節

對於sendto,Linux 核心最後會呼叫udp_sendmsg,大概的呼叫堆疊是 udp_sendmsg security_socket_sendmsg __sock_sendmsg sock_sendmsg sendto 在sento裡面,會根據socket的模式把