【发布时间】:2021-05-19 12:35:18
【问题描述】:
是的,我知道这个问题已经讨论过很多次了。 是的,我已经看过并阅读了这些和其他讨论:
1
2
3
我仍然无法自己修复代码。
我正在编写自己的网络服务器。在下一个循环中,它侦听一个套接字,连接每个新客户端并将其写入一个向量。
在我的课堂上,我有这个结构:
struct Connection
{
int socket;
std::chrono::system_clock::time_point tp;
std::string request;
};
使用下一个数据结构:
std::mutex connected_clients_mux_;
std::vector<HttpServer::Connection> connected_clients_;
还有循环本身:
//...
bind (listen_socket_, (struct sockaddr *)&addr_, sizeof(addr_));
listen(listen_socket_, 4 );
while(1){
connection_socket_ = accept(listen_socket_, NULL, NULL);
//...
Connection connection_;
//...
connected_clients_mux_.lock();
this->connected_clients_.push_back(connection_);
connected_clients_mux_.unlock();
}
它可以工作,客户端连接、发送和接收请求。 但问题是,如果连接断开(客户端为“^C”),那么我的程序即使在此刻也不知道它:
void SendRespons(HttpServer::Connection socket_){
write(socket_.socket,( socket_.request + std::to_string(socket_.socket)).c_str(), 1024);
}
正如这个问题的标题所示,我的应用收到了SIGPIPE 信号。
再次,我看到了“解决方案”。
signal(SIGPIPE, &SigPipeHandler);
void SigPipeHandler(int s) {
//printf("Caught SIGPIPE\n%d",s);
}
但这无济于事。此时,我们有了写入的套接字的“№”,是否可以“记住”它并在处理程序方法中关闭这个特定的连接?
我的系统:
Operating System: Ubuntu 20.04.2 LTS
Kernel: Linux 5.8.0-43-generic
g++ --version
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
【问题讨论】:
-
为什么不在您的 while 循环中以某种方式 ping 客户端,如果它失败初始化超时序列?
-
@user7778287 每个客户端每次写入? “真正的”服务器会这样做吗?
-
他们必须做点什么。如果有一种方法可以在不遍历列表的情况下发现每个 x 的状态,我急切地等待了解它..
-
解决方案是
signal(SIGPIPE, SIG_IGN);,而不是您发布的所谓解决方案。您还需要处理write调用返回和错误代码。