#include #include #include #include #include #include #include #include #include #include #define PORT 9999 #define TIMEOUT 3 pid_t play_pid = 0; // 启动播放 void start_playback() { if (play_pid == 0) { play_pid = fork(); if (play_pid == 0) { execl("./audio_play", "./audio_play", NULL); perror("execl failed"); exit(1); } printf("播放进程已启动,PID=%d\n", play_pid); } } // 停止播放 void stop_playback() { if (play_pid > 0) { printf("停止播放,终止 PID=%d\n", play_pid); kill(play_pid, SIGTERM); waitpid(play_pid, NULL, 0); play_pid = 0; } } int main() { int listen_fd, conn_fd; struct sockaddr_in addr; char buffer[128]; time_t last_time = 0; int playing = 0; fd_set read_fds; struct timeval tv; listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd < 0) { perror("socket error"); return 1; } int opt = 1; setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind error"); close(listen_fd); return 1; } if (listen(listen_fd, 5) < 0) { perror("listen error"); close(listen_fd); return 1; } printf("语音守护 TCP 服务器已启动,监听端口 %d...\n", PORT); while (1) { printf("等待客户端连接...\n"); conn_fd = accept(listen_fd, NULL, NULL); if (conn_fd < 0) { perror("accept error"); continue; } printf("客户端已连接\n"); last_time = 0; playing = 0; // 设置非阻塞模式 fcntl(conn_fd, F_SETFL, O_NONBLOCK); while (1) { FD_ZERO(&read_fds); FD_SET(conn_fd, &read_fds); tv.tv_sec = 1; tv.tv_usec = 0; int ret = select(conn_fd + 1, &read_fds, NULL, NULL, &tv); if (ret > 0 && FD_ISSET(conn_fd, &read_fds)) { ssize_t len = read(conn_fd, buffer, sizeof(buffer) - 1); if (len > 0) { buffer[len] = '\0'; if (strstr(buffer, "RUNNING")) { last_time = time(NULL); if (!playing) { printf("收到心跳,启动播报...\n"); start_playback(); playing = 1; } } } else if (len == 0) { printf("客户端关闭连接\n"); break; } } else if (ret == 0) { // 超时 if (playing && (time(NULL) - last_time > TIMEOUT)) { printf("超时未收到心跳,停止播报...\n"); stop_playback(); playing = 0; } } else { perror("select error"); break; } } close(conn_fd); // 断开连接时停止播放 if (playing) { printf("连接断开,停止播放\n"); stop_playback(); playing = 0; } } close(listen_fd); return 0; }