簡體   English   中英

c socket()函數中類型和協議有什么區別?

[英]What is the difference between type and protocol in c socket() function?

我正在閱讀並嘗試了解C ,並且幾年前我嘗試使用UDPTCP 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM