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數據一樣)。