为什么写入一个关闭的 TCP 套接字比读取一个更糟糕?

2024-01-15

当您读取关闭的 TCP 套接字时,您会收到一个常规错误,即它返回 0 表示 EOF 或 -1 以及错误代码errno可以打印perror http://www.opengroup.org/onlinepubs/000095399/functions/perror.html.

但是,当您编写一个关闭的 TCP 套接字时,操作系统会发送SIGPIPE到您的应用程序,如果没有被捕获,它将终止该应用程序。

为什么写入关闭的 TCP 套接字比读取它更糟糕?


+1 To 格雷格·休吉尔 https://stackoverflow.com/questions/2216374/why-is-writing-a-closed-tcp-socket-worse-than-reading-one/2216386#2216386引导我的思维过程朝着正确的方向寻找答案。

真正的原因是SIGPIPE套接字和管道中的过滤器习惯用法/模式适用于 Unix 系统中的典型 I/O。

从管道开始。像 grep 这样的过滤程序通常会写入STDOUT并从中读取STDIN,它可以被 shell 重定向到管道。例如:

cat someVeryBigFile | grep foo | doSomeThingErrorProne

shell 当它分叉然后执行这些程序时可能使用dup2 http://linux.die.net/man/2/dup2系统调用重定向STDIN, STDOUT and STDERR到适当的管道。

自过滤程序grep不知道也无法知道它的输出已被重定向,那么告诉它停止写入损坏的管道的唯一方法是:doSomeThingErrorProne崩溃是有信号的,因为写入的返回值STDOUT很少被检查过。

带插座的模拟将是inetd http://en.wikipedia.org/wiki/Inetd服务器取代了 shell。

作为一个例子,我假设你可以转grep进入一个网络服务,该服务运行于TCP插座。例如与inetd如果你想拥有一个grep服务器开启TCP端口 8000 然后将其添加到/etc/services:

grep     8000/tcp   # grep server

然后将其添加到/etc/inetd.conf:

grep  stream tcp nowait root /usr/bin/grep grep foo

Send SIGHUP to inetd并使用 telnet 连接到端口 8000。这应该会导致inetd要分叉,请将套接字复制到STDIN, STDOUT and STDERR然后执行grep以 foo 作为参数。如果您开始在 telnet 中输入行grep将回显那些包含 foo 的行。

现在用名为的程序替换 telnetticker例如,将实时股票报价流写入STDOUT并获取命令STDIN。有人远程登录到端口 8000 并输入“start java”以获取 Sun Microsystems 的报价。然后他们起床去吃午饭。 telnet 莫名其妙地崩溃了。如果没有SIGPIPE然后发送ticker会永远不断地发送报价,永远不知道另一端的进程已经崩溃,并且不必要地浪费系统资源。

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

为什么写入一个关闭的 TCP 套接字比读取一个更糟糕? 的相关文章

  • 域套接字“sendto”遇到“errno 111,连接被拒绝”

    我正在使用域套接字从另一个进程获取值 就像 A 从 B 获取值一样 它可以运行几个月 但最近 A 向 B 发送消息时偶尔会失败 出现 errno 111 连接被拒绝 我检查了B域套接字绑定文件 它是存在的 我也在另一台机器上做了一些测试 效
  • 基于非 HTTP 协议的 REST 示例

    REST 在 HTTP 之外的其他协议上的工作效果如何 对于使用 REST 或可能使用 REST 的协议 是否有任何好的示例 我认为你不会找到很多 但是here https datatracker ietf org doc draft ie
  • 面向对象编程语言中的引用默认情况下是否应该不可为空? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 套接字接收全部

    我正在尝试在 C 中捕获 ip 数据包 一切工作正常 除了我只收到传出的数据包 My Code using Socket sock new Socket AddressFamily InterNetwork SocketType Raw P
  • “对象之间通过传递消息进行通信”到底是如何实现的?

    在几本有关面向对象编程的介绍性文本中 我遇到过上述陈述 来自维基百科 在 OOP 中 每个对象都能够接收消息 处理数据 以及发送消息与其他对象相关 并且可以被视为具有独特角色或责任的独立 机器 该语句在代码中到底意味着什么 class A
  • 确定我可以向文件句柄写入多少内容;将数据从一个 FH 复制到另一个 FH

    如何确定是否可以将给定数量的字节写入文件句柄 实际上是套接字 或者 如何 取消读取 我从其他文件句柄读取的数据 我想要类似的东西 n how much can I write w handle n read r handle buf n a
  • SocketIO + Flask 检测断开连接

    我在这里有一个不同的问题 但意识到它可以简化为 如何检测客户端何时从页面断开连接 关闭其页面或单击链接 换句话说 套接字连接关闭 我想制作一个带有更新用户列表的聊天应用程序 并且我在 Python 上使用 Flask 当用户连接时 浏览器发
  • 使用ssl和socket的python客户端身份验证

    我有一个 python 服务器 需要客户端使用证书进行身份验证 我如何制作一个客户端脚本 使用客户端证书由 python 中的服务器使用 ssl 和套接字模块进行身份验证 有没有仅使用套接字和 ssl 而不扭曲的示例 from OpenSS
  • Socket.io 如何判断某人何时离开

    我正在使用 socket io 创建一个实时游戏 目前 当有人离开时 什么也不会发生 我想以某种方式通知服务器说谁离开了 有没有办法在用户离开时发出正确的信息 我可以让服务器每 1000 毫秒对每个人执行一次 ping 操作 或者通过其他方
  • 我可以关闭并重新打开套接字吗?

    我学习了一个使用套接字的例子 在此示例中 客户端向服务器发送请求以打开套接字 然后服务器 侦听特定端口 打开套接字 一切都很好 套接字从双方 客户端和服务器 打开 但我仍然不清楚这个东西有多灵活 例如 客户端是否可以关闭一个打开的 从两端
  • Python服务器“通常只允许每个套接字地址使用一次”

    我正在尝试用 python 创建一个非常基本的服务器 它侦听端口 当客户端尝试连接时创建 TCP 连接 接收数据 发回某些内容 然后再次侦听 并无限期地重复该过程 这是我到目前为止所拥有的 from socket import server
  • Nginx 和 Flask-socketio Websockets:存在但没有消息传递?

    我在让 Nginx 与 Python Flask socketio 库 基于 gevent 很好地配合时遇到了一些麻烦 目前 由于我们正在积极开发 我正在尝试让 Nginx 充当代理 对于发送页面 我可以通过直接运行flask socket
  • uwsgi协议比http协议快吗?

    我正在尝试部署 django 应用程序的各种设置 我的第一选择是使用带有 mod wsgi 的简单 apache 服务器 我之前已经实现了该服务器供私人使用 由于当前的部署是供公众使用的 因此我正在考虑各种选择 根据网上提供的信息 使用 n
  • 您使用什么来通过其自定义协议来测试(功能/负载/压力)您的网络服务?

    我最近创建了一个回合制游戏服务器 可以接受数十万个并发客户端连接 长话短说 Linux 上的 epoll 通信基于简单 定制 基于线路的协议 该服务器允许客户端连接 寻找游戏比赛中的其他玩家 玩所述游戏 发送动作 聊天消息等 并在游戏结束时
  • 套接字发送调用被阻塞很长时间

    我每 10 秒在套接字上发送 2 个字节的应用程序数据 阻塞 但发送调用在下面的最后一个实例中被阻塞超过 40 秒 2012 06 13 12 02 46 653417 信息 发送前 2012 06 13 12 02 46 653457 信
  • 如何读取 UDP 连接直至超时?

    我需要读取 UDP 流量 直到超时 我可以通过在 UDPConn 上调用 SetDeadline 并循环直到出现 I O 超时错误来做到这一点 但这看起来很黑客 基于错误条件的流量控制 下面的代码片段看起来更正确 但并没有终止 在生产中 这
  • Swift 中计算只读属性与函数

    在 Swift WWDC 简介会话中 只读属性description被证明 class Vehicle var numberOfWheels 0 var description String return numberOfWheels wh
  • 获取Windows下新线程/删除线程的通知

    创建 DLL 时 您可以在 DllMain 函数 DLL THREAD ATTACH DLL THREAD DETACH 中获取有关新线程 退出线程的通知 有没有办法在 非托管 可执行文件中从 Windows 获取这些或等效通知 是的 在您
  • “流类型”套接字和“数据报”套接字类型有什么区别?

    流类型 套接字和 数据报 套接字类型有什么区别 简短的回答是 消息边界和连接 使用流套接字 您可以写入两条五字节消息并最终读取一条十字节消息 这是因为您写入的数据只是放入单个流中 写入的数据之间没有边界 这就像一次向文件写入一个单词一样 作
  • 网络服务发现不是发现服务类型

    我想通过 Android 设备在本地网络中找到服务器 我可以通过使用找到它NSDManager具有服务器服务类型的服务 例如 workstation tcp是服务类型 在我的本地网络中我有一个 无线路由器和无线中继器 两者都有不同的SSID

随机推荐