c - socket() 中“type”为 SOCK_DGRAM 或 SOCK_STREAM 时是否需要指定“protocol”?
问题描述
来自 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) 了解如何将协议名称字符串映射到协议编号。
因此是否需要指定协议字段取决于域和类型字段。假设域是AF_INET
,即 IPv4,则协议字段应设置为 0SOCK_DGRAM
和SOCK_STREAM
。的手册页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) 函数作为 socket(AF_INET, socket_type, protocol) 调用来创建 IP 套接字。有效的套接字类型是 SOCK_STREAM 用于打开 tcp(7) 套接字,SOCK_DGRAM 用于打开 udp(7) 套接字,或 SOCK_RAW 用于打开 raw(7) 套接字以直接访问 IP 协议。protocol 是要接收或发送的 IP 头中的 IP 协议。 协议的唯一有效值是 TCP 套接字的 0 和 IPPROTO_TCP,以及 UDP 套接字的 0 和 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
字段,尽管手册页没有说明允许哪些值。
推荐阅读
- mysql - 如何选择另一个表中不存在的值?
- javascript - 是否可以覆盖 JS 中的函数,同时保留其原始词法范围?
- php - 引用单词并用逗号分隔它们
- python - 如何在 Python 中列出所有邻居?
- python - Importing a file to python and executing it multiple times
- automation - Is there a way to shuffle series’ in VLC or some type of video player, to play series at random but episodes in order?
- java - How let loop of buttons comunicate to each other
- c# - How can I save a captured picture from the user to the cosmos db in xamarin forms?
- reactjs - 即使在重新加载选项后,下拉列表的选定值仍然存在
- sql - SQL 在一段时间后重新初始化值