jelasin 的學(xué)生作業(yè):
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX_EVENTS 1024
#define BUFFER_SIZE 4096
#define WORKER_NUM 4
int create_udp_socket(int port) {
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
perror("bind failed");
close(sockfd);
exit(EXIT_FAILURE);
}
return sockfd;
}
void worker_process(int sockfd) {
int epoll_fd = epoll_create1(0);
if (epoll_fd < 0) {
perror("epoll_create1 failed");
exit(EXIT_FAILURE);
}
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = sockfd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sockfd, &ev) < 0) {
perror("epoll_ctl failed");
close(epoll_fd);
exit(EXIT_FAILURE);
}
struct epoll_event events[MAX_EVENTS];
char buffer[BUFFER_SIZE];
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
while (1) {
int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
if (nfds < 0) {
if (errno == EINTR) continue;
perror("epoll_wait failed");
break;
}
for (int i = 0; i < nfds; i++) {
if (events[i].data.fd == sockfd) {
ssize_t recv_len = recvfrom(sockfd, buffer, BUFFER_SIZE, 0,
(struct sockaddr*)&client_addr, &addr_len);
if (recv_len < 0) {
perror("recvfrom failed");
continue;
}
printf("Worker[%d] received %zd bytes from %s:%d\n",
getpid(), recv_len,
inet_ntoa(client_addr.sin_addr),
ntohs(client_addr.sin_port));
// Echo back
sendto(sockfd, buffer, recv_len, 0,
(struct sockaddr*)&client_addr, addr_len);
}
}
}
close(epoll_fd);
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s \n", argv[0]);
exit(EXIT_FAILURE);
}
int port = atoi(argv[1]);
int sockfd = create_udp_socket(port);
signal(SIGCHLD, SIG_IGN);
for (int i = 0; i < WORKER_NUM; i++) {
pid_t pid = fork();
if (pid < 0) {
perror("fork failed");
exit(EXIT_FAILURE);
} else if (pid == 0) {
// Child process
worker_process(sockfd);
exit(EXIT_SUCCESS);
}
}
printf("Server started with %d workers on port %d\n", WORKER_NUM, port);
printf("Master process PID: %d\n", getpid());
while (1) {
sleep(1);
}
close(sockfd);
return 0;
}