欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1647|回復: 0
打印 上一主題 下一主題
收起左側

從緩沖上看阻塞與非阻塞socket在發送接收上的區別

[復制鏈接]
跳轉到指定樓層
樓主
ID:107189 發表于 2016-3-5 17:13 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
   最近在網絡上看到一些帖子以及回復,同時又搜索了一些網絡上關于阻塞非阻塞區別的描述,發現很多人在描述兩者的發送接收時操作返回以及緩沖區處理的區別時有不同程度的誤解。所以我想寫一篇文章來糾正錯誤,并作為記錄方便查閱,如有轉載,注明作者(jwybobo2007)以及出處即可。
  首先socket在默認情況下是阻塞狀態的(未指異步操作以及其它一些特殊用途下,直接默認為非阻塞),這就使得發送以及接收操作處于阻塞的狀態,即調用不會立即返回,而是進入睡眠等待操作完成。下面把討論點分為發送以及接收。
一.發送選用send(這里特指TCP)以及sendto(這里特指UDP)來描述
    首先需要說明的是,不管阻塞還是非阻塞,在發送時都會將數據從應用緩沖區拷貝到內核緩沖區(SO_RCVBUF選項聲明,除非緩沖區大小為0)。我在網絡上看到某些人說,阻塞就是將數據真正發送給對方,并且阻塞是發生在需要把前面的所有數據全部發送出去,然后再發送本次的,而非阻塞則是拷貝到發送緩沖區。我不得不說,上面的這種說法是錯誤的。
    在阻塞模式下send操作將會等待所有數據均被拷貝到發送緩沖區后才會返回。
    如果當前發送緩沖總大小為8192,已經拷貝到緩沖的數據為8000,那剩余的大小為192,現在需要發送2000字節數據,那阻塞發送就會等待緩沖區足夠把所有2000字節數據拷貝進去,如第一次拷貝進192字節,當緩沖區成功發送出1808字節后,再把應用緩沖區剩余的1808字節拷貝到內核緩沖,而后send操作返回成功發送字節數。
    從上面的過程不難看出,阻塞的send操作返回的發送大小,必然是你參數中的發送長度的大小。
    在阻塞模式下的sendto操作不會阻塞。
    關于這一點的原因在于:UDP并沒有真正的發送緩沖區,它所做的只是將應用緩沖區拷貝給下層協議棧,在此過程中加上UDP頭,IP頭,所以實際不存在阻塞。
    在非阻塞模式下send操作調用會立即返回。
    關于立即返回大家都不會有異議。還是拿阻塞send的那個例子來看,當緩沖區只有192字節,但是卻需要發送2000字節時,此時調用立即返回,并得到返回值為192。從中可以看到,非阻塞send僅僅是盡自己的能力向緩沖區拷貝盡可能多的數據,因此在非阻塞下send才有可能返回比你參數中的發送長度小的值。
    如果緩沖區沒有任何空間時呢?這時肯定也是立即返回,但是你會得到WSAEWOULDBLOCK/E WOULDBLOCK 的錯誤,此時表示你無法拷貝任何數據到緩沖區,你最好休息一下再嘗試發送。
    在非阻塞模式下sendto操作 不會阻塞(與阻塞一致,不作說明)。

二.接收選用recv(這里特指TCP)以及recvfrom(這里特指UDP)來描述
    在阻塞模式下recv,recvfrom操作將會阻塞 到緩沖區里有至少一個字節(TCP)或者一個完整UDP數據報才返回。
    在沒有數據到來時,對它們的調用都將處于睡眠狀態,不會返回。
    在非阻塞模式下recv,recvfrom操作將會立即返回。
    如果緩沖區 有任何一個字節數據(TCP)或者一個完整UDP數據報,它們將會返回接收到的數據大小。而如果沒有任何數據則返回錯誤 WSAEWOULDBLOCK/E WOULDBLOCK。

  以上是關于阻塞非阻塞發送接收的區別以及在緩沖區處理上的差別,希望給看到這篇文章的人一些幫助。同時也想糾正網絡上的某些錯誤觀點,文章中表述如有錯誤,望大家指正,謝謝。

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表