帶外數據OOB與緊急模式URG

 傳輸層協議使用帶外數據(out-of-band,OOB)來發送一些重要的數據,如果通信一方有重要的數據需要通知對方時,協議能夠將這些數據快速地發送到對方.爲了發送這些數據,協議一般不使用與普通數據相同的通道,而是使用另外的通道.linux系統的套接字機制支持低層協議發送和接受帶外數據.但是TCP協議沒有真正意義上的帶外數據.爲了發送重要協議,TCP提供了一種稱爲緊急模式(urgent mode)的機制.TCP協議在數據段中設置URG位,表示進入緊急模式.接收方可以對緊急模式採取特殊的處理.很容易看出來,這種方式數據不容易被阻塞,可以通過在我們的服務器端程序裏面捕捉SIGURG信號來及時接受數據或者使用帶OOB標誌的recv函數來接受.

  Intel® 主動管理技術 (Intel AMT) 就是使用的OOB.

A,TCP支持帶外數據OOB?與緊急模式URG有什麼關係?
     TCP
支持帶外數據,是隻有一個OOB字節,TCP的帶外數據是通過緊急模式URG實現的
.
B,
我們知道send(sendfd,"ABC",3,MSG_OOB),將發送3個字節的帶外數據OOB數據.但是這裏TCP又只支持一個字節的OOB,難道丟掉2個字節
?
     TCP將把緊急模式
URG 置位,緊急指針定位第三個字節("C")(這裏不管它的具體位置,緊急指針的作用就是提供定位那個OOB字節的信息),前兩個字節("AB")當作普通字節發送.其實TCP總是把最後一個字節當作OOB數據,其他的當作普通字節.不管你通過帶MSG_OOB標誌的sendxxx函數發送多少字節帶外數據OOB數據,發送端只把最後一個字節當作OOB數據,接收端也只能收到一個字節的OOB數據
.
C,
如果一定要發送多字節的帶外數據,讓接收端能一次收到多個字節的帶外數據.能不能做到
?
    
對於TCP協議,不能
!
D,
對於TCP,收到的帶外數據怎麼保存
?
    
兩種模式
:
     1,
OOBINLINE 模式,這是套接字的默認模式,OOB字節與普通字節分開存放.存放在一個OOB緩衝區中,當然TCP只有一個字節,以用一個字節保存OOB數據
.
     2,OOBINLINE
模式,OOB字節和普通字節一起存放,它和普通字節本來就是一起發送,當然可以一起存放
.
E,recv(recvfd,buff,256,MSG_OOB).
會有哪些結果
?
     recvxxxx函數,在MSG_OOB模式下,將在OOB緩衝區中尋找數據。
     如果發送端沒發送OOB字節,它返回錯誤
.
    
如果發送端發送了OOB字節
:
     1,
對於非OOBINLINE 模式,它返回1字節的OOB數據
.
     2,
對於OOBINLINE 模式,返回錯誤.因爲OOB字節沒有放到OOB緩衝區中
.
F,
如果發送端使用MSG_OOB模式,send(sendfd,sndbuff,64,MSG_OOB),發送了包含"OOB字節"64字節數據,然後用非MSG_OOB模式,send(sendfd,sndbuff,64,0)發送64字節,當接收端收到64+64字節的數據後,recv(recvfd,revbuff,256,0).會有哪些結果
?
1,
對於非OOBINLINE 模式,第一次recv(recvfd,revbuff,256,0)只返回前63字節的普通數據,接收緩衝區剩下64字節.要獲得1字節的OOB數據,必須使用MSG_OOB模式的revxxx函數.再次recv(recvfd,revbuff,256,0),返回第二次發送的64字節.一次recvxxx不跨越urg-mark標記
.
2,
對於OOBINLINE 模式,第一次recv(recvfd,revbuff,256,0)只返回前63字節的普通數據,接收緩衝區剩下65字節(OOB+64字節),第二次recv(recvfd,revbuff,256,0),對於windows,只返回一字節的OOB字節,需要第三次rev才能返回最後的64字節,對於linux/unix,第二次rev 就返回65字節(OOB+64字節).之與協議棧的實現有關
.
G,
如果OOB字節沒被應用程序讀取,協議棧又收到了新的OOB字節,出現什麼情況
?
    TCP
協議對每個socket保持一個URG指針,此時直接刷新URG指針,指向新的OOB字節
.
對於非OOBINLINE,舊的OOB字節直接被丟棄,被新的OOB字節覆蓋
(經過本人測試,舊的OOB字節並不會被丟棄,而是被放入普通數據的接受緩衝區).
對於OOBINLINE,舊的OOB字節仍然在接收緩衝區中,但被當着普通數據看待,每個socket只有一個URG指針,只能定位一個OOB字節.

 

注:經測試發現,OOBINLINE是否設置帶來的區別僅僅在於讀取URG字節的時候是否需要MSG_OOB標誌,其他包括sockatmark函數,新到OOB字節時對於尚未被讀出的OOB字節的處理都是相同的。另外,即使在SIGURG處理函數中已經使用MSG_OOB讀出了OOB數據,只要在普通接收緩衝區中的讀指針還沒有越過帶外標記,OOB數據還是會被放入普通的接收緩衝區中(行爲與沒有讀出OOB數據一樣)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章