language-agnostic - 为什么写一个关闭的 TCP 套接字比读一个更糟糕?

标签 language-agnostic sockets network-programming network-protocols

当您读取关闭的 TCP 套接字时,您会收到一个常规错误,即它返回 0 表示 EOF 或 -1 以及 errno 中的错误代码。可以用 perror 打印.

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

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

最佳答案

+1 至 Greg Hewgill将我的思维过程引导到正确的方向以找到答案。
SIGPIPE的真正原因套接字和管道中的过滤器习惯用法/模式适用于 Unix 系统中的典型 I/O。

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

cat someVeryBigFile | grep foo | doSomeThingErrorProne

shell 在 fork 然后执行这些程序时可能使用 dup2 重定向系统调用 STDIN , STDOUTSTDERR到适当的管道。

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

带 socket 的模拟将是 inetd server 代替了 shell。

举个例子,我假设你可以转 grep进入在 TCP 上运行的网络服务 socket 。例如 inetd如果你想拥有一个 grep服务器在 TCP端口 8000 然后将此添加到 /etc/services :
grep     8000/tcp   # grep server

然后将此添加到 /etc/inetd.conf :
grep  stream tcp nowait root /usr/bin/grep grep foo

发送 SIGHUPinetd并使用 telnet 连接到端口 8000。这应该会导致 inetd叉,将 socket 复制到 STDIN , STDOUTSTDERR然后执行 grep以 foo 作为参数。如果您开始在 telnet 中输入行 grep将回显那些包含 foo 的行。

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

关于language-agnostic - 为什么写一个关闭的 TCP 套接字比读一个更糟糕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2216374/

相关文章:

C# NetworkStream 数据丢失

c# - 在 C# 中查找接口(interface)索引

c# - 跟踪 TCP 上已连接客户端的最佳方法是什么?

c++ - 如何在 C++ 中透明地处理不同的协议(protocol)版本?

c - TCP/IP 客户端发送

model-view-controller - *** MVC应用程序后,还有人喜欢N层架构吗?

java - 有没有办法确定哪个 OutputStream 当前正在发送到我的套接字输入流?

linux - 如何处理EPOLLERR和EPOLLHUP?

插件架构的安全/认证

algorithm - 如何从多边形内的点获取多边形外最近的点?