size_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
src_addr
参数以什么字节顺序写入?网络还是主机?我在recvfrom
手册页或通过google和SO搜索中找不到此内容。
答案 0 :(得分:5)
假设套接字是IPv4或IPv6套接字,则src_addr
中存储的主机和端口将按照网络字节顺序。
man page for 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主机地址。结构的s_addr
成员in_addr
包含网络字节顺序的主机接口地址。 应该为in_addr
分配一个INADDR_*
值(例如,INADDR_LOOPBACK
)使用htonl(3)或使用inet_aton(3)进行设置, inet_addr(3),inet_makeaddr(3)库函数或直接与 名称解析器(请参阅gethostbyname(3))。
ipv6手册页具有类似的措辞。
因此,在读取端口号时,请使用ntohs
来提取它。读取地址时,请使用inet_ntop
将其转换为文本形式。