来自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
吗?
答案 0 :(得分:2)
在socket(2)
的手册页中:
协议指定要与之配合使用的特定协议 的 插座。通常仅存在一个协议来支持特定协议 给定协议系列中的套接字类型,在这种情况下,协议可以 指定为0。但是,可能有许多协议 存在,在这种情况下,必须在此指定特定协议 方式。使用的协议号特定于“通信” 进行通讯的领域”;参见协议(5)。看到 getprotoent(3)关于如何将协议名称字符串映射到协议编号。
因此是否需要指定协议字段取决于域和 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,套接字类型,协议)。有效插座 类型为SOCK_STREAM以打开tcp(7)套接字,SOCK_DGRAM 打开udp(7)套接字,或SOCK_RAW打开raw(7)套接字 直接访问IP协议。 protocol是IP协议中的 要接收或发送的IP标头。 的唯一有效值 TCP通讯协定的通讯协定为0和IPPROTO_TCP,而0和 用于UDP套接字的IPPROTO_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
字段。