如何在C ++中使用键盘输入终止侦听TCP服务器

时间:2018-03-24 08:00:02

标签: c++ linux server serversocket

我试图找到一种方法来安全地关闭服务器,而不是在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;
    }

1 个答案:

答案 0 :(得分:2)

您需要添加另一个从stdin读取的线程,并在看到这些命令时毫不客气地退出应用程序,或者更改代码以使用selectpoll之类的命令来查看哪些描述符具有输入可用:添加stdin的描述符(出于您的目的,您可以信任它为0)以及侦听套接字的描述符,当其中一个或两个都有输入事件时,您select或{{ 1}}将返回 - 如果它告诉你stdin有数据 - 你可以不受阻塞地读取它:如果你看到你的终止命令,退出。

对于poll / select,您应该将您正在调用的套接字poll设置为非阻塞,因为可以通知传入的连接尝试但是您转到accept该连接可能已经失败的时间 - 您也不希望accept阻止并停止acceptselect来电监控poll对你而言。

在这两个中,额外的线程是最简单的 - 这是一个最小的程序,说明如何启动它并让它监视stdin,而你的主线程正在做自己的东西。在Linux上,链接到stdin

-lpthread

(如果你想要“有序”关闭它会变得有点复杂,主线程中对象的析构函数可以保证运行....)