#include #include #include #include #include #include #include #include #include #include #include #include #define SERVER_IP "111.111.11.1" #define CLIENT_IP "111.111.11.2" #define PORT 8888 #define MAX_EVENTS 10 #define BUFFER_SIZE 1024 // 函数声明 void server_process(); void client_process(); int main() { pid_t pid = fork(); if (pid < 0) { perror("fork failed"); exit(EXIT_FAILURE); } else if (pid == 0) { // 子进程作为客户端 // 等待一秒,确保服务器已启动 sleep(1); client_process(); } else { // 父进程作为服务器 server_process(); } return 0; } // 服务器进程逻辑 void server_process() { printf("[Server] Starting server process...\n"); int listen_sock, conn_sock, epoll_fd; struct sockaddr_in server_addr, client_addr; socklen_t client_len = sizeof(client_addr); struct epoll_event ev, events[MAX_EVENTS]; char buffer[BUFFER_SIZE]; int data_processed = 0; // 添加标志位,标记是否已处理过数据 if ((listen_sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0)) < 0) { perror("[Server] socket creation failed"); exit(EXIT_FAILURE); } memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) { perror("[Server] inet_pton failed"); exit(EXIT_FAILURE); } if (bind(listen_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("[Server] bind failed"); exit(EXIT_FAILURE); } if (listen(listen_sock, 1) < 0) { perror("[Server] listen failed"); exit(EXIT_FAILURE); } printf("[Server] Listening on %s:%d\n", SERVER_IP, PORT); if ((epoll_fd = epoll_create1(0)) < 0) { perror("[Server] epoll_create1 failed"); exit(EXIT_FAILURE); } ev.events = EPOLLIN; ev.data.fd = listen_sock; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_sock, &ev) < 0) { perror("[Server] epoll_ctl: listen_sock failed"); exit(EXIT_FAILURE); } printf("Adding listening socket %d to epoll\n", listen_sock); while (!data_processed) { int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); if (nfds < 0) { perror("[Server] epoll_wait failed"); exit(EXIT_FAILURE); } for (int n = 0; n < nfds; ++n) { if (events[n].data.fd == listen_sock) { printf("trying to accept new connection...\n"); while (1) { conn_sock = accept(listen_sock, (struct sockaddr *)&client_addr, &client_len); if (conn_sock < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { printf("All incoming connections have been " "processed.\n"); break; } else { perror("accept error"); exit(EXIT_FAILURE); break; } } ev.events = EPOLLIN | EPOLLET; ev.data.fd = conn_sock; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, conn_sock, &ev) < 0) { perror("[Server] epoll_ctl: conn_sock failed"); exit(EXIT_FAILURE); } printf("[Server] Accepted connection from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); } } else { printf("[Server] handling client data...\n"); int client_fd = events[n].data.fd; int nread = read(client_fd, buffer, BUFFER_SIZE); if (nread == -1) { if (errno != EAGAIN) { perror("[Server] read error"); close(client_fd); } } else if (nread == 0) { printf("[Server] Client disconnected.\n"); close(client_fd); } else { buffer[nread] = '\0'; printf("[Server] Received from client: %s\n", buffer); write(client_fd, buffer, nread); printf("[Server] Echoed data back to client. Server will " "now exit.\n"); data_processed = 1; // 设置退出标志 sleep(3); close(client_fd); break; } } } } printf("[Server] Server process completed.\n"); close(listen_sock); close(epoll_fd); } // 客户端进程逻辑 void client_process() { printf("[Client] Starting client process...\n"); int sock = 0; struct sockaddr_in client_bind_addr, server_addr; char buffer[BUFFER_SIZE] = {0}; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("[Client] socket creation failed"); exit(EXIT_FAILURE); } memset(&client_bind_addr, 0, sizeof(client_bind_addr)); client_bind_addr.sin_family = AF_INET; client_bind_addr.sin_port = htons(7777); if (inet_pton(AF_INET, CLIENT_IP, &client_bind_addr.sin_addr) <= 0) { perror("[Client] inet_pton for bind failed"); exit(EXIT_FAILURE); } if (bind(sock, (struct sockaddr *)&client_bind_addr, sizeof(client_bind_addr)) < 0) { perror("[Client] bind failed"); exit(EXIT_FAILURE); } printf("[Client] Bound to IP %s\n", CLIENT_IP); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) { perror("[Client] inet_pton for connect failed"); exit(EXIT_FAILURE); } if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("[Client] connect failed"); exit(EXIT_FAILURE); } printf("[Client] Connected to server %s:%d\n", SERVER_IP, PORT); const char *message = "Hello from client"; write(sock, message, strlen(message)); printf("[Client] Sent: %s\n", message); sleep(1); int valread = read(sock, buffer, BUFFER_SIZE); if (valread > 0) { buffer[valread] = '\0'; printf("[Client] Received: %s\n", buffer); } printf("[Client] Client process completed.\n"); close(sock); }