[英]What is the difference between type and protocol in c socket() function?
我正在閱讀並嘗試了解C
,並且幾年前我嘗試使用UDP
和TCP
UDP
Java chat
程序,並且盡可能地將其刪除...我無法做到。 我想編寫套接字並且我正在閱讀大量的文檔,但總有一部分不清楚,每個踢文檔都有一個缺陷。 例如,有一個關於
int socket(int domain, int type, int protocol);
我將使用的域顯然是AF_INET
,如果我想要TCP
套接字,我認為類型應該是SOCK_STREAM
,但什么是協議? 文檔說它應該是0 ...為什么??? 它是什么?
從socket的手冊頁:
該協議指定了與套接字一起使用的特定協議。 通常,只有一個協議支持給定協議族中的特定套接字類型,在這種情況下協議可以指定為0.但是,可能存在許多協議,在這種情況下,必須在此指定特定協議方式。 要使用的協議號特定於進行通信的“通信域”; 見協議(5)。 有關如何將協議名稱字符串映射到協議號,請參閱getprotoent(3)。
根據協議的手冊頁:
此文件是純ASCII文件,描述了TCP / IP子系統中可用的各種DARPA Internet協議。 應該參考它而不是使用ARPA包含文件中的數字,或者更糟糕的是,只是猜測它們。 這些數字將出現在任何IP標頭的協議字段中。
每行的格式如下:
協議號別名...
...
/ etc / protocols協議定義文件。
在我的linux盒子上的/ etc / protocols文件中:
ip 0 IP # internet protocol, pseudo protocol number
hopopt 0 HOPOPT # hop-by-hop options for ipv6
icmp 1 ICMP # internet control message protocol
igmp 2 IGMP # internet group management protocol
ggp 3 GGP # gateway-gateway protocol
ipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'')
st 5 ST # ST datagram mode
tcp 6 TCP # transmission control protocol
cbt 7 CBT # CBT, Tony Ballardie <A.Ballardie@cs.ucl.ac.uk>
egp 8 EGP # exterior gateway protocol
igp 9 IGP # any private interior gateway (Cisco: for IGRP)
bbn-rcc 10 BBN-RCC-MON # BBN RCC Monitoring
...
並根據getprotocol的手冊頁:
getprotobyname()函數從數據庫返回與協議名稱名稱匹配的條目的protoent結構。 如有必要,將打開與數據庫的連接。
...
protoent結構定義如下:
struct protoent { char *p_name; /* official protocol name */ char **p_aliases; /* alias list */ int p_proto; /* protocol number */ }
因此,如果您將“ip”傳遞給getprotobyname(),它將返回0,這是您正在使用的數字。 但即使您不知道協議的名稱,直接使用0也總是安全的。
可能有不同的協議來支持特定的套接字類型,這就是為什么你也可以在socket(2)
指定protocol
的原因。
從聯機幫助頁(強調我的):
該協議指定了與套接字一起使用的特定協議。 通常,只有一個協議支持給定協議族中的特定套接字類型,在這種情況下協議可以指定為0. 但是,可能存在許多協議,在這種情況下,必須在此指定特定協議方式。
因此,它不是強制性的指定協議為0
。 實際上0
意味着標准庫將為您找出正確的協議。 但是你可以明確地指定它,這樣做是完全有效的。
在Linux上,您可以通過以下操作查看可用的協議:
$ cat /etc/protocols
# Internet (IP) protocols
#
# Updated from http://www.iana.org/assignments/protocol-numbers and other
# sources.
# New protocols will be added on request if they have been officially
# assigned by IANA and are not historical.
# If you need a huge list of used numbers please install the nmap package.
ip 0 IP # internet protocol, pseudo protocol number
hopopt 0 HOPOPT # IPv6 Hop-by-Hop Option [RFC1883]
icmp 1 ICMP # internet control message protocol
igmp 2 IGMP # Internet Group Management
ggp 3 GGP # gateway-gateway protocol
ipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'')
st 5 ST # ST datagram mode
socket()的最后一個協議參數可以與raw包一起使用。 我會嘗試解釋它。
如果使用原始套接字從TCP堆棧獲取數據包,則可以使用此參數控制要發送/接收的數據包數據量。
socket (AF_INET, SOCK_RAW, IPPROTO_TCP);
上面的調用將為您提供一個原始數據包,其中內核將處理數據包到IP頭。 您必須在發送數據包時手動填寫其余數據包,或者當您讀取數據包時,內核將提供TCP標頭的內容以及數據。
另一方面:
socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
使用IPPROTO_RAW ,您可以從IP層向上控制數據包。 即內核將為您提供以太網頭的服務,其余的數據包在您的控制之下。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.