在socket()函数中,当"type"为SOCK_DGRAM或SOCK_STREAM时,我们需要指定"protocol"吗?

4

来自APUE

#include <sys/socket.h>
int socket(int domain, int type, int protocol);

说明:

  • type 可以是 SOCK_DGRAM、SOCK_RAW、SOCK_SEQPACKET、SOCK_STREAM
  • protocol 可以是 IPPROTO_TCP、IPPROTO_UDP 等。

SOCK_DGRAM 可以与 IPPROTO_UDP 一起使用,但不能与 IPPROTO_TCP 一起使用吗?

SOCK_STREAM 可以与 IPPROTO_TCP 一起使用,但不能与 IPPROTO_UDP 一起使用吗?

如果答案是肯定的,这是否意味着在 typeSOCK_DGRAMSOCK_STREAM 的情况下,我们不需要指定 protocol

2个回答

3

根据socket(2)的手册:

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

因此,是否需要指定 protocol 字段取决于 domain type 字段。 假设域名是AF_INET,即IPv4,则对于SOCK_DGRAMSOCK_STREAM,协议字段都应设置为0。 ip(7) 的手册显示了这一点:

SYNOPSIS

   #include <sys/socket.h>
   #include <netinet/in.h>
   #include <netinet/ip.h> /* superset of previous */

   tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
   udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
   raw_socket = socket(AF_INET, SOCK_RAW, protocol);

...

An IP socket is created by calling the socket(2) function as socket(AF_INET, socket_type, protocol). Valid socket types are SOCK_STREAM to open a tcp(7) socket, SOCK_DGRAM to open a udp(7) socket, or SOCK_RAW to open a raw(7) socket to access the IP protocol directly. protocol is the IP protocol in the IP header to be received or sent. The only valid values for protocol are 0 and IPPROTO_TCP for TCP sockets, and 0 and IPPROTO_UDP for UDP sockets. For SOCK_RAW you may specify a valid IANA IP protocol defined in RFC 1700 assigned numbers.

< p > ipv6(7) 手册显示了不同的内容:

SYNOPSIS

   #include <sys/socket.h>
   #include <netinet/in.h>

   tcp6_socket = socket(AF_INET6, SOCK_STREAM, 0);
   raw6_socket = socket(AF_INET6, SOCK_RAW, protocol);
   udp6_socket = socket(AF_INET6, SOCK_DGRAM, protocol);

看起来在IPv6中,您可以指定protocol字段,尽管手册没有说明允许使用什么值。


2
dbush的回答已经过时了。这是当前man页面对于ip(7)的说明:
protocol is the IP protocol in the IP header to be received or sent.
Valid values for protocol include:


   •  0 and IPPROTO_TCP for tcp(7) stream sockets;

   •  0 and IPPROTO_UDP for udp(7) datagram sockets;

   •  IPPROTO_SCTP for sctp(7) stream sockets; and

   •  IPPROTO_UDPLITE for udplite(7) datagram sockets.

   For SOCK_RAW you may specify a valid IANA IP protocol defined in
   RFC 1700 assigned numbers.
如您所见,目前对于流式套接字和数据报套接字类型,存在两种不同的协议。而protocol参数则用于指定相应套接字类型所使用的协议。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接