【问题标题】:Why does POSIX not define a mid-layer socket API?为什么 POSIX 没有定义中间层套接字 API?
【发布时间】:2015-02-08 18:09:58
【问题描述】:

我又在看套接字编程了。我得到了细节(嗯,我可以从各种网站复制它们,而且我知道代码启用了 Unix 低级程序),但我没有得到 POSIX 逻辑和 API 中的思考。

  • 为什么他们没有在这些低级套接字函数的基础上定义一个稍微高级一点的接口?
    据推测,此类代码可以将经常重复(且容易出错)的代码分解为更方便的FILE 类接口。当较低级别的使用在 > 90% 的使用中相同时,保理似乎比仅仅方便更合适。我在应用程序中看到的几乎所有使用的套接字都打开一个套接字,读取和写入它并关闭套接字。另外,为什么需要绑定,而这确实是 open 调用总是做的事情?

  • 当前界面甚至涵盖了哪些情况下,看起来几乎像 FILE 界面的界面无法轻松覆盖?
    一种解释是,例如,有些用途不会绑定到套接字,或者类似 fgets/fputs/fprintf/fscanf 的功能需要额外的东西(超时)?

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

【问题讨论】:

    标签: c sockets posix standard-library


    【解决方案1】:

    重点非常简单:

    因为套接字是不是文件。

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

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

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

    编辑:send 不会“抛出”错误。 “抛出”不是处理错误的 C/Posix 方法。相反,它会返回一个错误(来自man 2 send):

    如果消息太长,无法通过底层协议原子传递,则返回错误EMSGSIZE,消息不传输。

    【讨论】:

    • " 如果我​​尝试发送的数据超出协议数据包缓冲区的容量,则会引发错误!"它不会。它会告诉你它还没有发送所有字节,因为它们不适合,你需要注意这一点。
    • @black:我的澄清是否同意你的看法?
    • 这是另一个可能的失败原因。但我的意思是当你尝试发送一个缓冲区并且它已部分发送时,你需要再次调用send,从它停止的地方开始。
    • 这通常不会发生——缓冲区通常以原子方式发送,或者根本不发送。
    • 很抱歉,我们仍然走在两条不同的道路上。请阅读here
    【解决方案2】:

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

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

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

    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 层终止进程外没有刷新,这与在 three 立即发送的send 不同。

    【讨论】:

      猜你喜欢
      • 2010-12-28
      • 1970-01-01
      • 2010-10-25
      • 1970-01-01
      • 2022-09-27
      • 2010-10-16
      • 2018-07-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多