【发布时间】:2014-09-15 05:50:23
【问题描述】:
我有两个应用程序,一个服务器和另一个客户端,都是用 C++ 和 Qt 编写的,但它们都使用 C 库,该库使用 C 套接字方法在它们之间执行套接字通信(这一切都在 Linux 中)。
当它们都连接并且我关闭客户端时,当服务器尝试向它发送新消息时,它会收到一个 SIGPIPE 错误并关闭。我在网络上和 SO 中做了一些研究,看看如何为 SIGPIPE 创建一个处理程序,所以我不会关闭应用程序,而是告诉不断发送信息的计时器停止。
现在我确实学会了如何简单地处理信号:创建一个接收 int 的方法并在 main() 或 global 中使用 signal(SIGPIPE, myMethod) (注意:从 SO 学到的,是的,我知道信号( ) 已过时)。
但问题是通过这种方式我无法停止向死客户端发送信息,因为处理信号的方法需要在发送消息的类之外或静态方法,无权访问我的服务器对象。
为了澄清,这里是当前的架构:
//main.cpp
void signal_callback_handler(int signum)
{
qDebug() << "Caught signal SIGPIPE" << signum << "; closing the application";
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
app.setApplicationName("ConnEmulator");
app.setApplicationVersion("1.0.0");
app.setOrganizationName("Embrasul");
app.setOrganizationDomain("http://www.embrasul.com.br");
MainWidget window;
window.show();
/* Catch Signal Handler SIGPIPE */
signal(SIGPIPE, signal_callback_handler);
return app.exec();
}
//MainWidget类(简体)
MainWidget::MainWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::MainWidget),
timerSendData(new QTimer(this))
{
ui->setupUi(this);
connect(timerSendData,SIGNAL(timeout()),this,SLOT(slotSendData()));
timerSendData->start();
//...
}
void MainWidget::slotSendData()
{
//Prepares data
//...
//Here the sending message is called with send()
if (hal_socket_write_to_client(&socket_descriptor, (u_int8_t *)buff_write, myBufferSize) == -1)
qDebug() << "Error writting to client";
}
//套接字库
int hal_socket_write_to_client(socket_t *obj, u_int8_t *buffer, int size)
{
struct s_socket_private * const socket_obj = (struct s_socket_private *)obj;
int retval = send(socket_obj->client_fd, buffer, size, 0);
if (retval < 0)
perror("write_to_client");
return retval;
}
那么我怎样才能让我在 int main() 中创建的 MainWidget 对象处理信号,以便他可以调用 timerSendData->stop()?
【问题讨论】:
-
这不是重复的。被标记为重复的问题甚至没有提到
SIGPIPE或任何关于信号的东西;它只是处理不相关的网络错误情况。 -
这是关于处理 ECONNRESET,这是您在处理 SIGPIPE 时得到的。没有任何“无关”的东西。一个的答案就是另一个的答案。
-
@EJP:
ECONNRESET是读取时可能出现的错误,而不是写入时出现的错误,与SIGPIPE无关。