【问题标题】:What byte order does recvfrom() save src_addr as?recvfrom() 将 src_addr 保存为什么字节顺序?
【发布时间】:2019-07-31 17:18:52
【问题描述】:

size_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)

src_addr 参数以什么字节顺序写入?网络还是主机?我在 recvfrom 手册页或通过 google 和 SO 搜索时找不到这个。

【问题讨论】:

标签: c linux recvfrom


【解决方案1】:

假设套接字是 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 大多数网络功能在缺少此设置时返回EINVALsin_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转成文本格式。

【讨论】:

  • 谢谢 - 你知道我在哪里可以查到的吗?我有点惊讶它不在手册页中。或者这是假设的网络编程“领域知识”?
  • @StoneThrow man 7 ipman 7 ipv6 分别包含有关使用 IPv4 和 IPv6 套接字的一般信息。
  • @bishop:你在排版过时的版本 6。当前版本 7 在这里:pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
猜你喜欢
  • 2014-12-29
  • 2015-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-26
  • 2010-11-27
  • 2012-01-23
  • 2010-09-30
相关资源
最近更新 更多