gpt4 book ai didi

C++ 和 OpenSSL : SIGPIPE when writing in closed pipe

转载 作者:太空狗 更新时间:2023-10-29 12:14:03 25 4
gpt4 key购买 nike

我正在为 Linux 上的 TCP 连接编写 C++ SSL 服务器。当程序使用 SSL_write() 写入关闭的管道时,会抛出 SIGPIPE 异常,导致程序关闭。我知道这是正常行为。但是当对等方没有正确关闭连接时,程序不应该总是死掉。

我已经在谷歌上搜索了很多,并尝试了几乎所有我发现的东西,但似乎没有什么对我有用。 signal(SIGPIPE,SIG_IGN) 不起作用 - 仍然会抛出异常(与 signal(SIGPIPE, SomeKindOfHandler) 相同。

gdb 输出:

Program received signal SIGPIPE, Broken pipe.
0x00007ffff6b23ccd in write () from /lib/x86_64-linux-gnu/libpthread.so.0
(gdb) where
#0 0x00007ffff6b23ccd in write () from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x00007ffff7883835 in ?? () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#2 0x00007ffff7881687 in BIO_write () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#3 0x00007ffff7b9d3e0 in ?? () from /lib/x86_64-linux-gnu/libssl.so.1.0.0
#4 0x00007ffff7b9db04 in ?? () from /lib/x86_64-linux-gnu/libssl.so.1.0.0
#5 0x000000000042266a in NetInterface::SendToSubscribers(bool) () at ../Bether/NetInterface.h:181
#6 0x0000000000425834 in main () at ../Bether/main.cpp:111

关于代码:

我正在使用一个正在等待新连接并接受它们的线程。然后线程将连接信息(BIO 和 SSL)放入 NetInterface 类内的静态映射中。每 5 秒 NetInterface::sendTOSubscribers()main() 执行一次。此函数访问静态映射并将数据发送到其中的每个连接。这个函数也是 SIGPIPE 的来源。我在 main()(显然在 5 秒循环之前)和 NetInterface::SendToSubscribers() 中使用了 signal(SIGPIPE,SIG_IGN) >,但它在任何地方都不起作用。

感谢您的帮助!

最佳答案

您必须调用函数 sigaction 来更改此行为,以忽略 SIGPIPE 或使用您自己的信号处理程序以特定方式处理它。请不要使用函数信号,它已过时。

http://man7.org/linux/man-pages/man2/sigaction.2.html

一种方法(我没有编译这段代码,但应该是这样的):

void sigpipe_handler(int signal)
{
...
}

int main()
{
struct sigaction sh;
struct sigaction osh;

sh.sa_handler = &sigpipe_handler; //Can set to SIG_IGN
// Restart interrupted system calls
sh.sa_flags = SA_RESTART;

// Block every signal during the handler
sigemptyset(&sh.sa_mask);

if (sigaction(SIGPIPE, &sh, &osh) < 0)
{
return -1;
}

...
}

如果程序是多线程的,情况会有所不同,因为您对接收信号的线程的控制较少。这取决于信号的类型。对于 SIGPIPE,它将被发送到生成信号的 pthread。尽管如此,sigaction 应该可以正常工作。

可以在主线程中设置掩码,所有随后创建的 pthreads 将继承信号掩码。否则,可以在每个线程中设置信号掩码。

sigset_t blockedSignal; 
sigemptyset(&blockedSignal);
sigaddset(&blockedSignal, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &blockedSignal, NULL);

但是,如果您阻止信号,它将等待处理,并会尽快交付。对于这种情况,请在线程末尾使用 sigtimedwait。在主线程或生成 SIGPIPE 的线程中设置的 sigaction 也应该有效。

关于C++ 和 OpenSSL : SIGPIPE when writing in closed pipe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32040760/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com