奇怪的SIGPIPE循环
Strange SIGPIPE in loop
在处理了我正在编写的c++程序中的一个非常奇怪的错误后,我决定编写以下测试代码,以证实我的怀疑。在原始程序中,在一个循环中调用send()
和this_thread::sleep_for()
(任意时间)16次导致发送失败,并产生SIGPIPE
信号。然而在这个例子中,它在4次之后就失败了。
我有一个服务器运行端口25565绑定到本地主机。最初的程序被设计为与这个服务器通信。我在这个测试代码中使用了相同的一个,因为它没有提前终止连接。
int main()
{
struct sockaddr_in sa;
memset(sa.sin_zero, 0, 8);
sa.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &(sa.sin_addr));
sa.sin_port = htons(25565);
cout << "mark 1" << endl;
int sock = socket(AF_INET, SOCK_STREAM, 0);
connect(sock, (struct sockaddr *) &sa, sizeof(sa));
cout << "mark 2" << endl;
for (int i = 0; i < 16; i++)
{
cout << "mark 3" << endl;
cout << "sent " << send(sock, &i, 1, 0) << " byte" << endl;
cout << "errno == " << errno << endl;
cout << "i == " << i << endl;
this_thread::sleep_for(chrono::milliseconds(2));
}
return 0;
}
在GDB中运行它是我发现它正在发出SIGPIPE的方式。下面是输出:http://pastebin.com/gXg2Y6g1
在另一个测试中,我在循环中调用this_thread::sleep_for()
16次,然后调用send()
一次。这不会产生相同的错误。它毫无问题地运行着。
在另一个测试中,我注释掉了线程睡眠行,它一直运行得很好。我在原始程序和上面的测试代码中都这样做了。
这些结果让我相信这不是服务器关闭连接的情况,即使这通常是SIGPIPE的意思(为什么没有调用this_thread::sleep_for()
时它运行得很好?)。
你知道是什么原因导致的吗?
在我的机器上运行这个程序一次打印到标记3,正如我所期望的那样。事实上,它在你的端运行了几次,告诉我你有一个服务器监听端口25565,你没有在这个问题中包括。
你的问题是你没有测试看看服务器是否关闭了连接,你没有告诉我们。当它这样做时,您的进程获得SIGPIPE
。因为你没有处理这个信号,你的进程退出。
你可以做些什么来解决这个问题:
- 开始检查函数返回值。在这种特殊情况下,它没有帮助,但是您忽略了
connect
和send
的潜在错误。我希望这是因为最小化程序,但是值得一提。 - 处理信号。如果您希望在代码的主要流程中处理服务器关闭,您可以注册一个忽略信号的处理程序,或者将标志
MSG_NOSIGNAL
传递给send
。在这两种情况下,send都将返回-1
,而errno
被设置为EPIPE
。 - RTFM。认真对待。一个简单的
man send
和搜索SIGPIPE
会给你这个答案。
至于为什么服务器关闭,如果不知道它是什么服务器以及它运行的是什么协议,我无法回答这个问题。不,不要在评论里回答这个问题。这与这个问题无关。简单的事实是,您正在与之通信的服务器可能随时关闭连接,您的代码必须能够处理这种情况。
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 为什么我的for循环不能正确获取argv
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- while循环中while循环的时间复杂度是多少
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 为什么在这个代码结束循环中没有得到结束
- 在基于范围的for循环中使用结构化绑定声明
- 用于C++中带有数组和指针的循环
- 循环中的随机函数
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 奇怪的SIGPIPE循环