我有一个小型服务器程序,它接受TCP或本地UNIX套接字上的连接,读取一个简单的命令,并根据命令发送一个回复.问题是客户端有时可能对答案没兴趣并且提前退出,因此写入该套接字将导致SIGPIPE并使我的服务器崩溃.什么是防止崩溃的最佳做法?有没有办法检查线的另一边是否还在读?(select()似乎在这里不起作用,因为它总是说套接字是可写的).或者我应该用处理程序捕获SIGPIPE并忽略它?
一个非常标准的C++ TCP服务器程序,使用pthreads,bind,listen和accept.我有一个场景,当我杀死一个连接的客户端时服务器结束(读取:崩溃).
崩溃的原因是write()对文件的调用失败,因此程序收到一个SIGPIPE.我想,这会让服务器退出.
我想,"当然,未处理的信号意味着退出",所以让我们使用signal():
signal(SIGPIPE, SIG_IGN);
Run Code Online (Sandbox Code Playgroud)
因为,取自man 2 write:
EPIPE fd 连接到读取端关闭的管道或插座.当发生这种情况时,写入过程也将收到SIGPIPE信号.(因此,仅当程序捕获,阻止或忽略此信号时才会看到写入返回值.)
唉,没有.无论是在服务器线程还是客户端线程中,这似乎都没有帮助.
那么,如何阻止write()呼叫发出该信号,或者(务实)如何阻止服务器退出.
我的诊断是:
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)