为什么 POSIX 不定义中间层套接字 API?

Why does POSIX not define a mid-layer socket API?

我又在看套接字编程了。我得到了详细信息(好吧,我可以从各种网站复制它们,而且我知道代码正在启用​​ Unix 低级程序),但我不明白 POSIX 中的逻辑和思考 API.

我失踪肯定是有原因的。否则,20 年后,已经有一个或多个标准库可以促进这一点,并且将得到广泛使用。我在 google 上找不到一个模仿所有 FILE 例程的程序。

要点非常简单:

因为套接字是不是文件。

让我详细说明:recv/send 的工作方式与 read/write 非常相似,如果您限制自己从头开始线性读取文件,并且在其末尾追加。

但是,你会说,send不让我写任意长度的数据槽!如果我尝试发送超出协议数据包缓冲区容量的数据,它会抛出错误!

这实际上就是套接字的美妙之处:您实际上将数据发送出去。你不能保留它;一旦发送就消失了,一旦收到就不会存储。套接字为您提供了一组完全不同的能力(例如,发送小于网络最大数据包大小的数据包),另一方面要求您自己进行一些控制。

编辑:send 不会 "throw" 错误。 "throwing" 不是 C/Posix 处理错误的方式。相反,它将 return 一个错误(来自 man 2 send):

If the message is too long to pass atomically through the underlying protocol, the error EMSGSIZE is returned, and the message is not transmitted.

C 编程语言现在是并且可能永远是一种轻量级语言。您需要了解 C 基本上可以在任何地方运行,有些东西需要长期的研究和工作才能标准化。
此外,我还看到添加了新的库,因为 C++ 领先并使它们成为标准,因此这是一种 C 共享。

请注意,您可以 "bind" 通过fdopen(3) 将套接字连接到文件并将其视为二进制文件。当然,您仍然需要绑定它,让它监听、接受以及您可以在不适用于文件的套接字上执行的所有操作。
事实上,尽管有相似的接口,套接字仅部分充当 UNIX 文件:甚至有一个 errno 值,ENOTSOCK 表示对非套接字文件描述符的套接字特定操作。

此外,考虑缓冲。您确实希望文件写入以大块的形式完成,因此需要更大的缓冲,以使其更快;这不适用于套接字,因为您需要立即发送数据,即不延迟。 考虑这个例子:

char one = '1', two = '2', three = '3';
   fwrite(&one, 1, 1, socket_file);
   fprintf(socket_file, "%c\n", two);
   send(fd, &three, 1, 0);

其中 fd 是连接的 socket(AF_INET, SOCK_STREAM, 0)socket_file = fdopen(fd, "w+")。接收方将读取 312,因为除了 FILE 层的进程终止外没有刷新,这与 send 不同,其中 three 立即发送。