为了实现循环执行命令并能够多次从TCP客户端接收命令,您需要对上面的代码进行一些修改。下面是一个修改后的示例,它将在接收到新的TCP连接后进入一个循环,不断地读取命令、执行命令,并将结果发送回客户端,直到客户端断开连接。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
void execute_command(char *cmd, char *result, int result_size) {FILE *fp;fp = popen(cmd, "r");if (fp == NULL) {snprintf(result, result_size, "Failed to execute command.\n");return;}char buffer[BUFFER_SIZE] = {0};while (fgets(buffer, sizeof(buffer), fp) != NULL) {strncat(result, buffer, result_size - strlen(result) - 1);}pclose(fp);
}
int main() {int server_fd, new_socket;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);char buffer[BUFFER_SIZE] = {0};char response[BUFFER_SIZE] = {0};// 创建socket文件描述符if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 绑定socket到端口8080if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt");exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}// 监听是否有客户端连接if (listen(server_fd, 3) < 0) {perror("listen");exit(EXIT_FAILURE);}while (1) {// 接受客户端连接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept");exit(EXIT_FAILURE);}// 循环读取和执行命令while (1) {// 清空缓冲区memset(buffer, 0, BUFFER_SIZE);memset(response, 0, BUFFER_SIZE);// 读取数据ssize_t bytes_received = read(new_socket, buffer, BUFFER_SIZE - 1);if (bytes_received <= 0) {// 如果读取失败或连接已关闭,跳出循环break;}printf("Received command: %s\n", buffer);// 执行命令并将结果存储在response中execute_command(buffer, response, BUFFER_SIZE);// 将执行结果发送回客户端send(new_socket, response, strlen(response), 0);printf("Response sent.\n");}// 关闭客户端连接close(new_socket);}// 关闭服务器socketclose(server_fd);return 0;
}
这个修改后的服务器会不断地接受客户端连接,并在每个连接上循环读取命令和发送结果,直到客户端断开连接。服务器会继续监听新的连接。
安全警告:这个服务器会无限制地执行接收到的任何命令,这非常危险。在实际应用中,您应该添加权限检查、命令验证和其他安全措施来防止未授权的访问和执行。此外,您应该限制可以执行命令的上下文,例如使用沙箱环境或限制执行特定类型的命令。