通过接收tcp命令实现程序自我重新运行

一个用 C++ 实现的示例程序,该程序监听 TCP 连接,当接收到特定的自定义协议命令(这里是 "RESTART")时,会重新运行自身。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define PORT 12345
#define BUFFER_SIZE 1024

void handle_connection(int sockfd)
{
    struct sockaddr_in client_addr;
    socklen_t client_addr_len = sizeof(client_addr);
    int client_socket = accept(sockfd, (struct sockaddr*)&client_addr, &client_addr_len);
    if(client_socket == -1)
    {
        perror("accept");
        return;
    }

    char buffer[BUFFER_SIZE];
    ssize_t bytes_received = recv(client_socket, buffer, BUFFER_SIZE - 1, 0);
    if(bytes_received > 0)
    {
        buffer[bytes_received] = '\0';
        if(std::string(buffer) == "RESTART")
        {
            std::cout << "Received restart command, restarting..." << std::endl;
            pid_t pid = fork();
            if(pid < 0)
            {
                perror("fork");
            }
            else if(pid == 0)
            {
                // 子进程
                close(sockfd); // 关闭父进程的套接字
                execl("/bin/bash", "bash", "-c", "./tcp_restart_program", (char*)NULL);
                perror("execl");
                exit(EXIT_FAILURE);
            }
            else
            {
                // 父进程
                close(sockfd); // 关闭父进程的套接字
                close(client_socket);
                wait(NULL); // 等待子进程结束
                exit(EXIT_SUCCESS);
            }
        }
        else
        {
            std::cout << "Received unknown command: " << buffer << std::endl;
        }
    }
    close(client_socket);
}

int main()
{
    int server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if(server_socket == -1)
    {
        perror("socket");
        return 1;
    }

    // 设置 SO_REUSEADDR 选项
    int opt = 1;
    if(setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1)
    {
        perror("setsockopt");
        close(server_socket);
        return 1;
    }

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(PORT);

    if(bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
    {
        perror("bind");
        close(server_socket);
        return 1;
    }

    if(listen(server_socket, 5) == -1)
    {
        perror("listen");
        close(server_socket);
        return 1;
    }

    std::cout << "Waiting for connections..." << std::endl;

    while(true)
    {
        handle_connection(server_socket);
    }

    close(server_socket);
    return 0;
}

编译和运行步骤:

1.将上述代码保存为 tcp_restart_program.cpp

2.打开终端,使用以下命令编译代码:

g++ -o tcp_restart_program tcp_restart_program.cpp

3.运行编译后的可执行文件:

./tcp_restart_program

4.通过NetAssist 发送命令RESTART通过接收tcp命令实现程序自我重新运行_第1张图片

5.程序运行效果

通过接收tcp命令实现程序自我重新运行_第2张图片

总结:

  1. 此 C++ 程序在 Linux 系统上构建了一个 TCP 服务器,监听 12345 端口,等待客户端连接,同时设置了 SO_REUSEADDR 选项以避免端口占用问题。
  2. 当接收到客户端连接后,程序读取客户端发送的数据,若数据为 RESTART,则通过 fork 创建子进程,子进程重新启动程序,父进程等待子进程结束后退出。
  3. 若接收到的不是 RESTART 命令,程序会输出未知命令信息,之后关闭客户端连接,持续循环等待新的连接。

你可能感兴趣的:(tcp/ip,网络,网络协议)