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

菲林

我最近在读CSAPP。它在10.9节中说,由于以下原因,不应将标准I / O与套接字一起使用:

(1)标准I / O的限制

限制1:输入功能紧随输出功能。在没有中间调用fflush,fseek,fsetpos或rewind的情况下,输入函数不能跟随输出函数。fflush函数清空与流关联的缓冲区。后三个函数使用Unix I / O lseek函数重置当前文件位置。

限制2:输出功能紧随输入功能。除非输入函数遇到文件结尾,否则输出函数不能跟随输入函数,而不会介入调用fseek,fsetpos或rewind。

(2)在套接字上使用lseek函数是非法的。

问题1:如果我违反限制会怎样?我写了一个代码片段,它工作正常。

问题2:绕过限制2,一种方法如下:

File *fpin, *fpout;

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

/* Some Work Here */

fclose(fpin);
fclose(fpout);

在教科书中说:

关闭线程程序中已经关闭的描述符是灾难的根源。

为什么?

R .. GitHub停止帮助ICE

由于您引用了两次关闭错误,因此您的解决方法无法按书面要求运行。只要没有干预操作都可以打开新的文件描述符,两次关闭对单线程程序是无害的(第二次关闭只会对进行无害的操作EBADF),但是它们是多线程程序中的关键错误。考虑这种情况:

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

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

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

编辑:我想我没有回答您的问题1.如果您违反有关如何在stdio流上的输入和输出之间切换的规则,将会发生未定义的行为这意味着对其进行测试并确认其“有效”是没有意义的。这可能意味着:

  1. 您正在使用的C实现为这种情况下的情况提供了一个定义(作为其文档的一部分),并且与您想要的行为匹配。在这种情况下,您可以使用它,但是您的代码将无法移植到其他实现中。因此,这样做被认为是非常不好的做法。要么,

  2. 您只是偶然获得预期的结果,通常是在所使用的实现上内部实现相关功能的方式的副作用。在这种情况下,无法保证它不会遇到无法按预期方式运行的极端情况,或者在将来的发行版中它将继续以相同的方式工作,等等。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在目标 c 中接收 Web 套接字不能与 socket.io 库一起使用

来自分类Dev

Linux C标准I / O-为什么要进行双重复制

来自分类Dev

如何通过C中的套接字一起发送两个缓冲区?

来自分类Dev

为什么在我的C代码中不能将“ long long int”和“ int”一起使用?

来自分类Dev

在 C 中使用指针时,我们何时以及为什么需要使用 malloc?

来自分类Dev

为什么我们在c中使用函数返回指针以及函数返回指针的应用

来自分类Dev

MongoDB C#为什么不能将DateTime.Date与IQueryable一起使用?

来自分类Dev

MongoDB C#为什么不能将DateTime.Date与IQueryable一起使用?

来自分类Dev

为什么我们不能在C#中使用IteratorStateMachineAttribute?

来自分类Dev

为什么我们不能在C中使用变量作为e的值

来自分类Dev

为什么我们不能将C结构直接存储在NSArray中

来自分类Dev

为什么在带有ehcache的春季我们不能将@Cacheable与静态方法一起使用?

来自分类Dev

为什么C#Rx Subscribe()函数不能与“ async”关键字一起使用?

来自分类Dev

为什么C ++标准库与编译器而不是os捆绑在一起?

来自分类Dev

为什么不能将C ++ 11大括号初始化与宏一起使用?

来自分类Dev

为什么我的别名不能与“ sh -c”一起使用?

来自分类Dev

为什么我不能在 C# 中将“dotnet run”与 xUnit 一起使用?

来自分类Dev

为什么我们不能在C#中使用公共字段进行数据绑定?

来自分类Dev

为什么我们不能使用C中的表达式为全局变量赋值?

来自分类Dev

为什么我们不能在 C 编程语言中使用 a 而不是 &a 来存储变量 a 的值?

来自分类Dev

何时在C#中将“ new”关键字与结构一起使用

来自分类Dev

我们可以将QT与C#一起使用来创建GUI吗?

来自分类Dev

Netty使用标准套接字获得响应

来自分类Dev

“同步的I / O是否可以与关联的文件一起使用”是什么意思?

来自分类Dev

与标准HTML一起使用react.js

来自分类Dev

为什么我们不能对接口中的方法一起使用默认访问修饰符和抽象关键字?

来自分类Dev

套接字是否集成到C ++标准中?

来自分类Dev

标准I / O流-fgets()缓冲类型

来自分类Dev

标准I / O流-fgets()缓冲类型

Related 相关文章

  1. 1

    在目标 c 中接收 Web 套接字不能与 socket.io 库一起使用

  2. 2

    Linux C标准I / O-为什么要进行双重复制

  3. 3

    如何通过C中的套接字一起发送两个缓冲区?

  4. 4

    为什么在我的C代码中不能将“ long long int”和“ int”一起使用?

  5. 5

    在 C 中使用指针时,我们何时以及为什么需要使用 malloc?

  6. 6

    为什么我们在c中使用函数返回指针以及函数返回指针的应用

  7. 7

    MongoDB C#为什么不能将DateTime.Date与IQueryable一起使用?

  8. 8

    MongoDB C#为什么不能将DateTime.Date与IQueryable一起使用?

  9. 9

    为什么我们不能在C#中使用IteratorStateMachineAttribute?

  10. 10

    为什么我们不能在C中使用变量作为e的值

  11. 11

    为什么我们不能将C结构直接存储在NSArray中

  12. 12

    为什么在带有ehcache的春季我们不能将@Cacheable与静态方法一起使用?

  13. 13

    为什么C#Rx Subscribe()函数不能与“ async”关键字一起使用?

  14. 14

    为什么C ++标准库与编译器而不是os捆绑在一起?

  15. 15

    为什么不能将C ++ 11大括号初始化与宏一起使用?

  16. 16

    为什么我的别名不能与“ sh -c”一起使用?

  17. 17

    为什么我不能在 C# 中将“dotnet run”与 xUnit 一起使用?

  18. 18

    为什么我们不能在C#中使用公共字段进行数据绑定?

  19. 19

    为什么我们不能使用C中的表达式为全局变量赋值?

  20. 20

    为什么我们不能在 C 编程语言中使用 a 而不是 &a 来存储变量 a 的值?

  21. 21

    何时在C#中将“ new”关键字与结构一起使用

  22. 22

    我们可以将QT与C#一起使用来创建GUI吗?

  23. 23

    Netty使用标准套接字获得响应

  24. 24

    “同步的I / O是否可以与关联的文件一起使用”是什么意思?

  25. 25

    与标准HTML一起使用react.js

  26. 26

    为什么我们不能对接口中的方法一起使用默认访问修饰符和抽象关键字?

  27. 27

    套接字是否集成到C ++标准中?

  28. 28

    标准I / O流-fgets()缓冲类型

  29. 29

    标准I / O流-fgets()缓冲类型

热门标签

归档