size_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
参数以什么字节顺序src_addr
写入?网络还是主机?recvfrom
我在手册页或通过 google 和 SO 搜索时找不到这个。
假设套接字是 IPv4 或 IPv6 套接字,则存储的主机和端口src_addr
将按网络字节顺序排列。
这在IPv4 ( )的手册页中man 7 ip
记录如下:
地址格式
IP 套接字地址定义为 IP 接口地址和 16 位端口号的组合。基本 IP 协议不提供端口号,它们由更高级别的协议实现,
如 udp(7) 和 tcp(7)。在原始套接字上,sin_port 设置为 IP 协议。struct sockaddr_in { sa_family_t sin_family; /* address family: AF_INET */ in_port_t sin_port; /* port in network byte order */ struct in_addr sin_addr; /* internet address */ }; /* Internet address. */ struct in_addr { uint32_t s_addr; /* address in network byte order */ };
sin_family
始终设置为AF_INET
。这是必需的;在 Linux 2.2 中EINVAL
,当缺少此设置时,大多数网络功能都会返回。sin_port
包含网络字节顺序的端口。 低于 1024 的端口号称为特权端口(或有时:保留端口)。只有特权进程(在 Linux 上:在管理其网络命名空间的用户命名空间中具有 CAP_NET_BIND_SERVICE 能力的进程)可以绑定(2)到这些套接字。请注意,原始 IPv4 协议本身没有端口的概念,它们仅由 tcp(7) 和 udp(7) 等高级协议实现。
sin_addr
是 IP 主机地址。struct的s_addr
成员in_addr
包含按网络字节顺序排列的主机接口地址。in_addr
应该使用 htonl(3) 分配INADDR_*
值之一(例如,INADDR_LOOPBACK
)或使用 inet_aton(3)、inet_addr(3)、inet_makeaddr(3) 库函数或直接使用名称解析器设置(参见 gethostbyname(3))。
ipv6 手册页有类似的措辞。
所以在读取端口号的时候,用ntohs
它来解压。读取地址时,使用inet_ntop
将其转换为文本形式。