c socket()函数的类型和协议有什么区别?

Bri*_*man 6 c sockets tcp

我正在阅读,并试图了解C,并且尝试了编程Java chatwith UDPTCP几年前,但我付出了很多努力……我做不到。我想对套接字进行编程,并且正在阅读大量文档,但是总有一部分内容不清楚,每一个踢文档都有缺陷。例如,有一个关于

int socket(int domain, int type, int protocol);
Run Code Online (Sandbox Code Playgroud)

我将使用的域很明显AF_INET,如果我想要一个TCPSocket,我认为类型应该是SOCK_STREAM,但是什么是协议?文档说应该为0 ...为什么?它是什么?

Jer*_*iah 5

从套接字的手册页:

该协议指定要与套接字一起使用的特定协议。通常只存在一个协议来支持给定协议族中的特定套接字类型,在这种情况下,protocol 可以指定为 0。但是,可能存在许多协议,在这种情况下,必须在此指定特定协议方式。要使用的协议编号特定于进行通信的“通信域”;见协议(5)。有关如何将协议名称字符串映射到协议编号的信息,请参阅 getprotoent(3)。

根据协议的手册页:

该文件是一个纯 ASCII 文件,描述了可从 TCP/IP 子系统获得的各种 DARPA 互联网协议。应该参考它而不是使用 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
...
Run Code Online (Sandbox Code Playgroud)

根据 getprotocol 的手册页:

getprotobyname() 函数从数据库中返回与协议名称名称匹配的条目的原型结构。如有必要,将打开与数据库的连接。

...

原型结构定义如下:

struct protoent {
    char  *p_name;       /* official protocol name */
    char **p_aliases;    /* alias list */
    int    p_proto;      /* protocol number */
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您将“ip”传递给 getprotobyname() 它将返回 0,这是您无论如何都在使用的数字。但是,即使您不知道协议的名称,直接使用 0 始终是安全的。


Agi*_*gis 2

可能有不同的协议来支持特定的套接字类型,因此您也可以指定protocolin socket(2)

从联机帮助页(强调我的):

该协议指定与套接字一起使用的特定协议。通常,在给定协议族中只存在一个协议来支持特定的套接字类型,在这种情况下,协议可以指定为 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
Run Code Online (Sandbox Code Playgroud)