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

2024-01-09

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

(1) 标准I/O的限制

限制1:输入函数在输出函数之后。一个输入 如果没有中间调用,函数无法跟随输出函数 fflush、fseek、fsetpos 或倒回。 fflush 函数清空 与流关联的缓冲区。后三个函数使用 Unix I/O lseek 函数重置当前文件位置。

限制2:输出函数跟随输入函数。一个输出 如果没有中间调用,函数无法跟随输入函数 fseek、fsetpos 或倒回,除非输入函数遇到 文件结尾。

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

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

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

File *fpin, *fpout;

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

/* Some Work Here */

fclose(fpin);
fclose(fpout);

课本上是这么说的:

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

Why?


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

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

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

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

Edit:我想我跳过了回答你的问题 1。如果你违反了关于如何在 stdio 流上的输入和输出之间切换的规则,会发生什么未定义的行为。这意味着测试它并看到它“有效”是没有意义的;它可能意味着:

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 为什么在 lambda 内部引发异常是 C# 7 的一项功能? [复制]

    这个问题在这里已经有答案了 该语句在 VS2015 中无法编译 但在 VS2017 中可以编译 var example new Action gt throw new Exception 为了支持在 lambda 表达式内抛出异常 必须对
  • 线程独占数据:如何存储和访问?

    NET 中是否有可能将对象实例绑定到线程的当前执行上下文 这样在代码的任何部分我都可以做类似的事情CurrentThread MyObjectData DoOperation 并确保我访问特定于线程的数据 谢谢 你可以看一下线程静态属性 h
  • C++:字符串流有什么好处?

    谁能告诉我一些在 C 中使用字符串流的实际例子 即使用流插入和流提取运算符输入和输出到字符串流 您可以使用字符串流来转换任何实现operator lt lt 到一个字符串 include
  • Monitor.Pulse & Wait - 意外行为

    http www codeproject com Articles 28785 Thread synchronization Wait and Pulse demystified http www codeproject com Artic
  • 提取单花括号内的值

    我想要一个收藏 value 一个字符串使用正则表达式 例如 lorem ipsum field1 lorem ipsum field2 lorem ipsum field1 lorem ipsum field2 field3 我会得到 fi
  • .NET 中的 Class.forName() 等效项?

    动态获取对象类型然后创建它的新实例的 C 方法是什么 例如 如何在 C 中实现以下 Java 代码的结果 MyClass x MyClass Class forName classes MyChildClass newInstance Lo
  • 为什么 ObservableCollection 有两个集合构造函数?

    The 可观察集合 T https msdn microsoft com en us library ms668604类有两个构造函数 可以在其中传递项目集合 一个构造函数接受一个IEnumerable T 另一个List T 鉴于List
  • UI 线程正在阻塞调用 COM 对象的后台线程

    我正在开发一个通过第三方 COM 库与外部设备通信的应用程序 我试图让与设备的所有通信都通过后台线程 以防止通信问题搞砸我的应用程序 并消除在 UI 线程中进行通信所引入的一些其他复杂性 问题是 每当发生导致主 UI 线程阻塞的情况 即调用
  • 将 std::pair const 转换为 std::pair const 安全吗?

    理论上或实践上 安全吗reinterpret cast a std pair
  • 使用 FromBase64Transform 解码 base64 文件流

    The example https msdn microsoft com en us library system security cryptography frombase64transform 28v vs 110 29 aspx从M
  • 使用信号和槽更新指针

    我对 Qt 很陌生 请帮我解决这个问题 我正在使用线程在后台执行密集操作 同时我想更新 UI 所以我使用 SIGNALS 和 SLOTS 为了更新 UI 我发出一个信号并更新 UI 让我们考虑下面的示例代码 struct sample QS
  • WCF 服务中的缓冲区大小

    我们有一个 WCF 服务 它执行某些存储过程并将结果返回给 silverlight 客户端 某些存储过程最多返回 80K 行 下面给出的是 web config 中服务的设置
  • 当一对迭代器初始化时,向量是否知道先保留?

    考虑以下代码 struct MyData MyData const BYTE pData size t uSize bucket pData pData uSize std vector
  • 链接到ntdll.lib并调用ntdll.dll内部的函数

    我最近正在对私有 API 进行一些研究 我尝试调用诸如NtOpenFile在 ntdll dll 中LoadLibrary and GetProcAddress在运行时 幸运的是 它成功了 今天早上我在电脑上进行了文件搜索 发现ntdll
  • 从 AuthorizeAttribute 继承的属性不起作用

    我目前正在尝试根据用户角色在新的 ASP MVC 5 应用程序中实现安全性 目标是防止用户在没有特定角色 或更高角色 的情况下访问某些控制器或控制器方法 根据到目前为止我所读到的问题 我创建了一个继承 AuthorizeAttribute
  • 小数精度

    我使用小数类型进行高精度计算 货币 但我今天遇到了这个简单的划分 1 1 37 这应该再次得到 37 http www wolframalpha com input i 1 2F 281 2F37 29 http www wolframal
  • Selenium - 模式对话框存在 - 如何接受信息?

    我有以下问题 在页面上提交一些日期后 我有一个如图所示的模式对话框 我想单击 ENTER 来浏览该模式 但它不起作用 我有以下代码 driver FindElement By CssSelector input submit Click A
  • DbContext.SaveChangesAsync 异常处理

    当搭建新的脚手架时ApiController通过 Visual Studio 2013 中的异步操作和实体框架支持 某些方法可以包装DbContext SaveChangesAsync https msdn microsoft com en
  • 从其对象获取结构体字段的名称和类型

    例如 我有一个类似这样的结构 struct Test int i float f char ch 10 我有一个该结构的对象 例如 Test obj 现在 我想以编程方式获取字段名称和类型obj 是否可以 顺便说一句 这是 C 你正在要求C
  • 从 C/C++ 程序进行 Ping

    我想编写一个 C 或 C 程序 给定一个 IP 地址 对其进行 Ping 然后根据 Ping 是否成功执行进一步的操作 这个怎么做 尽情享受Ping 页面 http www ping127001 com pingpage htm 其中有一个

随机推荐

  • 设置对象 nil 与release+realloc

    这不是垃圾收集环境 我有一个类实例变量 在运行时的某个时刻 我需要使用与最初构造时不同的数据集重新初始化 假设地说 如果我有一个NSMutableArray or an NSMutableDictionary 做这样的事情会更有效率吗 my
  • 在 MVC 应用程序中使用 ELMAH 调试/跟踪消息

    我们如何在 MVC 应用程序中使用 ELMAH 添加调试 跟踪消息 ELMAH 通常用于报告异常 而不是作为一般的调试 跟踪日志 对于调试 跟踪日志记录 我建议结合使用log4net https stackoverflow com ques
  • 在 Redhat 5 上运行 JavaFX 应用程序

    From my 上一个问题 https stackoverflow com questions 24420651 javafx helloworld jar cannot be ran on different platform 我知道Re
  • Azure 服务总线空闲时自动删除

    我试图找出设置 AutoDeleteOnIdle 时的正确行为 我有一个名为 MyGameMessages 的主题 不透露游戏名称 因为它可能被视为广告 我所做的是在服务器场中的每个节点上创建一个订阅 var manager GetName
  • 活动模型序列化器:nil:NilClass 的未定义方法“url_for”

    我在用着active model serializersgem 在我的应用程序中发送高级 json 响应 它实际上工作正常 但由于我安装了该 gem 使用几分钟后 应用程序崩溃 显示上面的错误 不确定我的代码是否与之相关 但不知何故 我也需
  • 如何使用Java测量网络响应时间?

    我们有一个客户端和一个服务器 我想测量它们之间网络的响应时间 当我向服务器发送请求时 它应该立即响应我的请求 它应该像 ping 请求一样 以便服务器不会有处理时间 我怎样才能在Java中做到这一点 我通过从客户端向服务器发送带有时间戳的数
  • 控制文件下载

    我正在使用 TWebBrowser 为我的程序构建一个更新程序 OnCreate 时 TWebBrowser 导航到给定的 URL 要下载更新 用户需要单击链接 单击链接时会出现此弹出窗口 所以我想知道是否可以 绕过该弹出窗口并允许自动下载
  • JQueryMobile 自动完成点击条目不更改输入值

    我尝试使用 jquery mobile 进行自动完成输入 所以我在这里找到了一个演示 http demos jquerymobile com 1 4 0 listview autocomplete remote http demos jqu
  • Java静态导入导致编译错误。可能是编译器错误?

    这在 Eclipse JDT 中可以正常编译 但在 1 6 30 或 1 7 25 上则不行 package doh import static doh Wtf InnerClass innerclassMethod import java
  • SQL Server 级联

    我正在制作一个网站 用户可以在其中发布 帖子 然后用户可以对这些帖子进行 评论 我有一个包含 3 个表的数据库 一项包含用户信息 一项包含帖子信息 最后一项包含评论信息 我想设置规则 以便如果用户被删除 他们的所有帖子和评论都会被删除 如果
  • Vue 使用 select、v-for 和 v-model 预选值

    我在用着select with v model并有选项v for和对象作为值 选项是一些由id标识的元素 如何根据自定义相等性预先选择选项 在本例中为相等 id场地 我正在寻找类似于 angularjs 的东西track by from n
  • 在多级继承中从子类调用“大”父函数[重复]

    这个问题在这里已经有答案了 public class GrandParent public void walk public class Parent public void walk public class Child public v
  • JavaFX 中的样式文本?

    我正在将聊天客户端从 Swing 切换到 JavaFX 但遇到了图形问题 以前 我使用的是JTextPane插入样式文本 但切换到 FX 后 我找不到能够执行所需操作的单个组件JTextPane做了 并且从this https stacko
  • 在对话框中启用 GPS 后 Android 位置返回 null

    当我进入屏幕时 我会检查 GPS 是否已打开 如果未打开 则会显示启用 GPS 的对话框 当用户单击 是 时 onActivityResult gt GPS 已打开 我尝试获取位置 但始终返回 null 当我在 GPS 已打开的情况下进入屏
  • 意外标记“(”与 mv !(build) 附近出现语法错误

    我正在尝试使用 Jenkins 构建过程运行以下 shell 命令 mv build build 现在构建失败了 bin bash xe tmp jenkins2925091423898519645 sh tmp jenkins292509
  • 如何使用Pandoc图像对齐来对齐同一行中的两个图像?

    从 pandoc 文档我知道如何插入图像 http johnmacfarlane net pandoc README html images http johnmacfarlane net pandoc README html images
  • 在每个视图中包含用户模型

    我正在创建一个具有表单身份验证的 ASP NET MVC4 网站 但在以正确的方式在视图中包含多个模型时遇到了困难 具体来说 有一个属于给定视图的模型 例如 CartModel 但是 考虑到站点的当前 UI 部分视图中使用了一个模型 该模型
  • Helm _helpers.tpl:调用其他模板定义中定义的模板

    头盔 helpers tpl Helm 允许使用进行模板化 https golang org pkg text template 在 Kubernetes 的资源文件中 一个名为 helpers tpl通常用于使用以下语法定义 Go 模板助
  • 更新 Windows 服务的过程?自动还是手动?

    如果我的服务器上有 Windows 服务 更新该服务的 最佳实践 是什么 假设其中有一个错误 或者我需要向它添加更多功能 有没有办法可以关闭服务 修补它并以更自动化的方式启动并运行它 任何带有代码的链接都很棒 好吧 你总是可以在安装程序上升
  • C 标准 I/O 的限制以及为什么我们不能将 C 标准 I/O 与套接字一起使用

    我最近在读CSAPP 在10 9节中 它说标准I O不应该与socket一起使用 原因如下 1 标准I O的限制 限制1 输入函数在输出函数之后 一个输入 如果没有中间调用 函数无法跟随输出函数 fflush fseek fsetpos 或