gpt4 book ai didi

c - C 标准 I/O 的限制以及为什么我们不能将 C 标准 I/O 与套接字一起使用

转载 作者:行者123 更新时间:2023-12-01 12:45:20 26 4
gpt4 key购买 nike

我最近在读 CSAPP。在 10.9 节中,它说标准 I/O 不应该与 socket 一起使用,原因如下:

(1) The restrictions of standard I/O

Restriction 1: Input functions following output functions. An input function cannot follow an output function without an intervening call to fflush, fseek, fsetpos, or rewind. The fflush function empties the buffer associated with a stream. The latter three functions use the Unix I/O lseek function to reset the current file position.

Restriction 2: Output functions following input functions. An output function cannot follow an input function without an intervening call to fseek, fsetpos, or rewind, unless the input function encounters an end-of-file.

(2) It is illegal to use the lseek function on a socket.



问题一 : 如果我违反限制会发生什么?我写了一个代码片段,它工作正常。

问题2 : 要绕过限制 2,一种方法如下:
File *fpin, *fpout;

fpin = fdopen(sockfd, "r");
fpout = fdopen(sockfd, "w");

/* Some Work Here */

fclose(fpin);
fclose(fpout);

教科书上说,

Closing an already closed descriptor in a threaded program is a recipe for disaster.



为什么?

最佳答案

由于您引用的双重关闭错误,您的解决方法无法按书面说明工作。只要没有可以打开新文件描述符的干预操作,双重关闭在单线程程序中是无害的(第二次关闭将无害地失败 EBADF ),但它们是多线程程序中的关键错误。考虑这种情况:

  • 线程 A 调用 close(n) .
  • 线程 B 调用 open它返回 n存储为 int fd1 .
  • 线程 A 调用 close(n)再次。
  • 线程 B 调用 open再次返回 n再次,它被存储为 fd2 .
  • 线程 B 现在尝试写入 fd1并实际写入第二次调用 open 打开的文件中而不是第一个打开的。

  • 这可能导致大量文件损坏、信息泄漏(想象将密码写入套接字而不是本地文件)等。

    但是,问题很容易解决。而不是调用 fdopen两次使用相同的文件描述符,只需使用 dup复制它并将副本传递给 fdopen .通过这个简单的修复,stdio 可以完美地与套接字一起使用。它仍然不适合异步事件循环的使用,但是如果您将线程用于 IO,它会很好用。

    编辑:我想我跳过了回答你的问题 1。如果你违反了关于如何在 stdio 流上切换输入和输出的规则,会发生什么 未定义的行为 .这意味着测试它并看到它“有效”是没有意义的;它可能意味着:
  • 您正在使用的 C 实现为在这种情况下发生的情况提供了一个定义(作为其文档的一部分),并且它与您想要的行为相匹配。在这种情况下,您可以使用它,但您的代码将无法移植到其他实现。出于这个原因,这样做被认为是非常糟糕的做法。或者,
  • 您只是偶然获得了预期的结果,通常是您正在使用的实现内部如何实现相关功能的副作用。在这种情况下,不能保证它不会出现无法按预期运行的极端情况,或者它会在 future 的版本中继续以相同的方式工作,等等。
  • 关于c - C 标准 I/O 的限制以及为什么我们不能将 C 标准 I/O 与套接字一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20605967/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com