为什么Berkeley套接字需要进行字节交换?

3

我知道在传输中,大多数整数都是以大端格式表示的。

但是为什么要让应用程序负责在像 sockaddr_in 这样的数据结构中进行字节交换,而不是在内核中进行所有的低级工作呢?如果用户空间API更平台无关,不需要处理这个问题会更有意义。

为什么伯克利套接字API被设计成这样?


你是在谈论手动填写 sockaddr_in 结构体类似的操作吗?或者你是在谈论高于 TCP 级别存在的协议,需要将通过 recv 填充的缓冲区中的数据进行转换吗? - zwol
@zwol 我在谈论第一种情况。 - 0x400921FB54442D18
1
谢谢。我自己不知道这个问题的答案,但我认为这是一个有效的问题,希望有人知道。 - zwol
2
如果你要问关于旧API的每一个设计缺陷,那么你会忙上很长一段时间。是的,套接字API很糟糕,就像许多Unix/Posix API一样。 - EOF
这并不是同一个问题。这个问题询问的是设计决策。而你指出的那个问题,@Antti Haapala,是在询问技术上的必要性,或者说事情为什么可以这样工作,而不是为什么会被这样设计。 - Swiss Frank
显示剩余4条评论
2个回答

1
原因可能是历史原因
套接字API的发明(在1980年代)时,Sun-3(MC68030)和Sun-4(Sparc)工作站是主流。这些(按今天的标准)速度较慢的处理器的endianness很重要。
我忘记了细节,也许BSD套接字约定是为一些PDP-11VAX-780发明的。

但为什么应用程序要负担像sockaddr_in这样的结构中的字节交换,而不是内核呢?

可能是因为在1980年代,你不希望计算机(比您的手机慢一千倍)在内核空间花费太多(不可中断的)时间。

这个问题应该在https://retrocomputing.stackexchange.com/上问(它的答案在一些20世纪80年代的Unix内核源代码中)。


这仍然没有解释为什么这个低级实现细节被暴露给用户空间,然后又暴露给套接字库的用户。 - EOF
问题是重复的。 - Antti Haapala -- Слава Україні
Antti,不是重复项。EOF,在我的答案中有解释。 - Swiss Frank

1
我能想到的唯一技术优势是它允许应用程序进行一次转换并将其缓存。
然后,对于众多调用UDP的sendto()等函数,如果需要重新排序地址,则提供重新排序后的地址给操作系统,操作系统可以直接将其复制到传出的网络数据包中。
在内核中执行此操作的替代方法要求每次调用sendto()时都重复使用应用程序已知的相同地址,并且每次都要重新转换。
由于sendto()从中受益,因此它们使API的其余部分以相同的方式工作。

问题是重复的。 - Antti Haapala -- Слава Україні

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接