C++ 程序退出是自动立即关闭TCP端口

[2020-04-23 16:29:46] [library] asio::listen called from the wrong state
terminate called after throwing an instance of ‘websocketpp::exception’
what(): invalid state
Aborted

 最近在一个AI项目C++开发中,测试时遇到了一个恼人的问题,
 软件使用了websocketpp 作为通信方式,但是每次测试时,程序退出了,指定的websocket 端口8765 还是被占用着,需要过几分钟才会被系统释放。

如果能在程序退出时,自动立刻关闭端口呢?

经过一番实践,把核心相关代码分享给需要的朋友参考。

这个任务分解为以下3步:

  1. 程序退出时需要设置一个拦截器,在程序退出时自动调用
    在main() 函数中,注册
    const int autoCloseWebSocket = std::atexit(UsbInput::VirtualUsbServer::shutdownWebsocket);
    if (autoCloseWebSocket!= 0) {
    std::cerr << “注册WebSocket在程序退出时自动关闭失败.\n”;
    return EXIT_FAILURE;
    }

  2. websocketpp 如何关闭指定端口

    void VirtualUsbServer::shutdownWebsocket(){
    websocket_server.stop_listening();
    LOG(INFO)<< " Websocket端口已经关闭. " << std::endl;
    }

  3. 测试样本代码,确保可以正常工作。 具体代码如下:

#include 
#include 
#include 
#include "UsbEmulator.h"
#include "MouseDeviceParser.h"
#include "KeyboardDeviceParser.h"
#include "VirtualUsbServer.h"
#include "HappyTool.h"

#include 
#include 

#include 
#include 


void VirtualUsbServer::shutdownWebsocket(){
    websocket_server.stop_listening();
    LOG(INFO)<< " Websocket端口已经关闭. " << std::endl;
}


int main(int argc, char* argv[]) {
    /**
     日志级别
       glog 支持四种日志级别,INFO、WARNING、ERROR和FATAL。默认情况下,在打印完FATAL日志之后,程序将会终止。ERROR和FATAL的日志除了会写到日志中,还会输出到 stderr。
     */
    // 解析命令行参数
    gflags::ParseCommandLineFlags(&argc, &argv, true);
    // 初始化日志库
    google::InitGoogleLogging(argv[0]);
    
    google::SetLogDestination(google::INFO, "log/"); // 把日志同时记录文件,最低级别为INFO
     UsbInput::VirtualUsbServer serverInstance=UsbInput::VirtualUsbServer();
    
     const int autoCloseWebSocket = std::atexit(UsbInput::VirtualUsbServer::shutdownWebsocket);
      if (autoCloseWebSocket!= 0) {
          std::cerr << "注册WebSocket在程序退出时自动关闭失败.\n";
          return EXIT_FAILURE;
      }
     serverInstance.start_server();
     return 0;
}

你可能感兴趣的:(C++ 程序退出是自动立即关闭TCP端口)