相关疑难解决方法(0)

如何防止SIGPIPE(或正确处理它们)

我有一个小型服务器程序,它接受TCP或本地UNIX套接字上的连接,读取一个简单的命令,并根据命令发送一个回复.问题是客户端有时可能对答案没兴趣并且提前退出,因此写入该套接字将导致SIGPIPE并使我的服务器崩溃.什么是防止崩溃的最佳做法?有没有办法检查线的另一边是否还在读?(select()似乎在这里不起作用,因为它总是说套接字是可写的).或者我应该用处理程序捕获SIGPIPE并忽略它?

c io signals sigpipe broken-pipe

242
推荐指数
8
解决办法
19万
查看次数

如何防止SIGPIPE或阻止服务器结束?

一个非常标准的C++ TCP服务器程序,使用pthreads,bind,listenaccept.我有一个场景,当我杀死一个连接的客户端时服务器结束(读取:崩溃).

崩溃的原因是write()文件的调用失败,因此程序收到一个SIGPIPE.我想,这会让服务器退出.

我想,"当然,未处理的信号意味着退出",所以让我们使用signal():

signal(SIGPIPE, SIG_IGN);
Run Code Online (Sandbox Code Playgroud)

因为,取自man 2 write:

EPIPE fd 连接到读取端关闭的管道或插座.当发生这种情况时,写入过程也将收到SIGPIPE信号.(因此,仅当程序捕获,阻止或忽略此信号时才会看到写入返回值.)

唉,没有.无论是在服务器线程还是客户端线程中,这似乎都没有帮助.

那么,如何阻止write()呼叫发出该信号,或者(务实)如何阻止服务器退出.


我的诊断是:

  • 服务器线程启动,绑定,监听,接受.
  • 让客户端连接(例如通过telnet)
  • 发送一个pkill telnet崩溃客户端

不需要的行为:服务器退出,在gdb

... in write () at ../sysdeps/unix/syscall-template.S:82
82      T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
Run Code Online (Sandbox Code Playgroud)

回溯:

#0  ... in write () at ../sysdeps/unix/syscall-template.S:82
#1  ... in ClientHandler::mesg(std::string) ()
#2  ... in ClientHandler::handle() ()
#3  ... in …
Run Code Online (Sandbox Code Playgroud)

c c++ sockets signals client-server

18
推荐指数
3
解决办法
1万
查看次数

标签 统计

c ×2

signals ×2

broken-pipe ×1

c++ ×1

client-server ×1

io ×1

sigpipe ×1

sockets ×1