[英]Strange Linux socket protocols behaviour
對於使用socket()
時Linux上的協議定義之間的差異,我有些困惑。 我試圖使用socket(PF_INET, SOCK_STREAM, proto)
偵聽TCP上的連接,在我看來, proto
存在爭議,或者至少看起來很奇怪。
從<netinet/in.h>
:
...
IPPROTO_IP = 0, /* Dummy protocol for TCP. */
...
IPPROTO_TCP = 6, /* Transmission Control Protocol. */
...
同意/etc/protocols
:
ip 0 IP # internet protocol, pseudo protocol number
hopopt 0 HOPOPT # hop-by-hop options for ipv6
...
tcp 6 TCP # transmission control protocol
...
我從網上教程中學, 並從該名男子頁tcp(7)
您在使用初始化TCP套接字
tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
它絕對可以正常工作,並且肯定是一個TCP套接字。 使用上述參數初始化套接字的一件事是該代碼
struct timeval timeout = {1, 0};
setsockopt(tcp_socket, 0, SO_RCVTIMEO, &timeout, sizeof(timeout); // 1s timeout
// Exactly the same for SO_SNDTIMEO here
精絕,但替換所有協議參數(包括后沒有工作的socket()
與IPPROTO_TCP
,而不是IPPROTO_IP
他們有,如上述。
因此,在嘗試了差異之后,我需要問一些搜索問題:
IPPROTO_TCP
替換所有協議參數時,設置協議0顯然只是一個“虛擬” TCP時,設置超時時會出現錯誤92(“協議不可用”)? socket()
應該是流,數據報還是原始套接字的信息,反之亦然? (即,TCP是流協議,UDP是數據報協議,...) hopopt
,為什么它的協議號與'ip'相同? 非常感謝。
為socket
提供0協議只是意味着您要為family / socktype對使用默認協議。 在這種情況下,它是TCP,因此得到的結果與IPPROTO_TCP
相同。
您的錯誤是在setsockopt調用中。 正確的是
setsockopt(tcp_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); // 1s timeout
0不是協議,而是選項級別。 IPPROTO_TCP
是另一個選項級別,但是您不能將其與SO_RCVTIMEO
結合使用。 它只能與SOL_SOCKET
一起使用。 與IPPROTO_TCP
一起使用的是tcp(7)中列出的那些,例如TCP_NODELAY
。
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
應該工作正常。
作為協議傳遞0只是意味着,請給我默認值。 當處理IP時,在每個系統上哪個是用於流套接字的TCP和用於數據報套接字的UDP。 但是socket()可以用於許多其他事情,而不會給您提供TCP或UDP套接字。
socket()本質上是非常通用的。 socket(AF_INET, SOCK_STREAM, 0);
讀為 “給我IP協議系列中的流式套接字”。 傳遞0表示您對哪種協議沒有偏好-盡管TCP對於任何系統都是顯而易見的選擇。 但從理論上講,它可以為您提供SCTP套接字。
協議不隱含數據報或流套接字。 除了基於IP的協議外,還有更多協議,並且許多協議可以用於數據報或流模式,例如SS7網絡中使用的SCCP。
對於基於IP的協議,SCTP可以以基於數據報或流方式使用。 因此套接字(AF_INET,IPPROTO_SCTP); 會模棱兩可。 對於數據報套接字,還有其他選擇,UDP,DCCP,UDPlite。
插座(AF_INET,SOCK_SEQPACKET,0); 是另一個有趣的選擇。 它不能返回TCP套接字,TCP不是基於數據包的。 它不能返回並且使用UDP套接字,UDP無法保證順序傳送。 但是,如果系統支持,則SCTP套接字可以。
我沒有解釋為什么有人在linux netinet / in.h中發表評論“ dummy TCP”
hopopt是“按跳的IPv6 HOP”選項。 在IPv6中,協議鑒別符字段也用作擴展機制。 在IPv4數據包中,有一個協議字段,它是協議標識符,如果該IPv4數據報帶有TCP,則將其設置為IPPROTO_TCP。 如果該IPv4數據包還包含一些其他信息(選項),則它們將通過其他機制進行編碼。
IPv6的操作與此不同,如果有擴展名(選項),則該擴展名將在協議字段中進行編碼。 因此,如果IPv6數據包需要逐跳選項,則將IPPROTO_HOPOPTS放在協議字段中。 實際的逐跳選項還具有協議區分符,該協議區分符指示下一個協議是什么-可能是IPPROTO_TCP或另一個選項。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.