我试图找到一种方法来安全地关闭服务器,而不是在linux中使用经典的 ctrl + C 来监听传入的客户端连接。我想终止程序,例如键盘输入 Q 或-quit
等... 在按输入后立即执行此操作,而不是接受后,例如,客户端连接。我该如何实现呢?
这是我的示例代码。
int startSocketConnection() {
socketFD = socket(AF_INET, SOCK_STREAM, 0);
//TODO exceptions
if (socketFD < 0) {
std::cout << "\nError establishing socket...\nexiting..." << std::endl;
return (-1);
}
std::cout << "\nSocket server has been created..." << std::endl;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
server_addr.sin_port = htons(portNum);
//TODO exceptions
if ( (bind(socketFD, (struct sockaddr*) &server_addr, sizeof(server_addr))) < 0 ) {
std::cout << "Error binding connection, Socket has already been established" << std::endl;
return (-1);
}
std::cout << "Listening for incoming client connection..." << std::endl;
listen(socketFD, 1);
size = sizeof(client_addr);
while (sessionActive) {
newSocketFD = accept(socketFD, (struct sockaddr *) &client_addr, &size);
if (newSocketFD < 0) error("ERROR on accept");
//fork() returns child pid to parent, 0 to the child process.
pid = fork();
if (pid < 0) error("ERROR on fork");
//if child process...
if (pid == 0) {
close(socketFD);
//process client query...
sessionActive = dostuff(newSocketFD);
signal(SIGCHLD, SIG_IGN);
std::cout << "Child process terminated!" << std::endl;
exit(0);
}
else {
close(newSocketFD);
}
}
close(socketFD);
return 0;
}
答案 0 :(得分:2)
您需要添加另一个从stdin读取的线程,并在看到这些命令时毫不客气地退出应用程序,或者更改代码以使用select
或poll
之类的命令来查看哪些描述符具有输入可用:添加stdin
的描述符(出于您的目的,您可以信任它为0)以及侦听套接字的描述符,当其中一个或两个都有输入事件时,您select
或{{ 1}}将返回 - 如果它告诉你stdin有数据 - 你可以不受阻塞地读取它:如果你看到你的终止命令,退出。
对于poll
/ select
,您应该将您正在调用的套接字poll
设置为非阻塞,因为可以通知传入的连接尝试但是您转到accept
该连接可能已经失败的时间 - 您也不希望accept
阻止并停止accept
或select
来电监控poll
对你而言。
在这两个中,额外的线程是最简单的 - 这是一个最小的程序,说明如何启动它并让它监视stdin,而你的主线程正在做自己的东西。在Linux上,链接到stdin
。
-lpthread
(如果你想要“有序”关闭它会变得有点复杂,主线程中对象的析构函数可以保证运行....)