来自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
一起使用吗?
如果答案是肯定的,是否意味着当
protocol
是type
或SOCK_DGRAM
时,我们不需要指定SOCK_STREAM
?
来自
socket(2)
的手册页:
协议指定要使用的特定协议 这 插座。通常只有一个协议来支持特定的 给定协议族中的套接字类型,在这种情况下协议可以 被指定为 0。但是,许多协议可能会 存在,在这种情况下,必须在此指定特定协议 方式。要使用的协议号特定于“通信” 进行通信的域”;参见协议(5)。看 getprotoent(3) 了解如何将协议名称字符串映射到协议编号。
因此是否需要指定 protocol 字段取决于 domain 和 type 字段。假设域是
AF_INET
,即 IPv4,那么 SOCK_DGRAM
和 SOCK_STREAM
的协议字段都应设置为 0。 ip(7)
的手册页显示了以下内容:
概要
#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);
...
通过调用socket(2)函数创建IP套接字 作为套接字(AF_INET,套接字类型,协议)。有效插座 类型是用于打开 tcp(7) 套接字的 SOCK_STREAM、SOCK_DGRAM 打开 udp(7) 套接字,或 SOCK_RAW 打开 raw(7) 套接字 直接访问IP协议。协议是IP协议 要接收或发送的 IP 标头。 唯一有效的值 TCP 套接字的协议为 0 和 IPPROTO_TCP,0 和 IPPROTO_UDP 用于 UDP 套接字。 对于 SOCK_RAW,您可以指定一个有效的 RFC 1700 中定义的 IANA IP 协议分配的编号。
ipv6(7)
手册页显示了不同的内容:
概要
#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
字段,尽管手册页没有说明允许哪些值。
dbush 的答案已经过时了。以下是 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
参数指定对应的套接字类型使用其中哪一个。