#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <unistd.h>
#define MAX_EVENTS 100
#define BUFFER_SIZE 1024
int main() {
int server_fd, epoll_fd;
struct epoll_event events[MAX_EVENTS];
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == -1) {
perror("TCP socket creation failed");
exit(EXIT_FAILURE);
}
int udp_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (udp_fd == -1) {
perror("UDP socket creation failed");
exit(EXIT_FAILURE);
}
// 设置地址和端口
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
perror("TCP bind failed");
exit(EXIT_FAILURE);
}
if (bind(udp_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
perror("UDP bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 5) == -1) {
perror("TCP listen failed");
exit(EXIT_FAILURE);
}
// 创建 epoll 实例
epoll_fd = epoll_create1(0);
if (epoll_fd == -1) {
perror("epoll_create1 failed");
exit(EXIT_FAILURE);
}
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = server_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &event) == -1) {
perror("epoll_ctl for TCP failed");
exit(EXIT_FAILURE);
}
event.events = EPOLLIN;
event.data.fd = udp_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, udp_fd, &event) == -1) {
perror("epoll_ctl for UDP failed");
exit(EXIT_FAILURE);
}
while (1) {
int num_events = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
if (num_events == -1) {
perror("epoll_wait failed");
exit(EXIT_FAILURE);
}
for (int i = 0; i < num_events; i++) {
int fd = events[i].data.fd;
if (fd == server_fd) {
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_len);
// 将新的 TCP 套接字添加到 epoll 实例中
event.events = EPOLLIN;
event.data.fd = client_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &event) == -1) {
perror("epoll_ctl for new TCP connection failed");
exit(EXIT_FAILURE);
}
printf("New TCP connection established.\n");
} else if (fd == udp_fd) {
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
char buffer[BUFFER_SIZE];
ssize_t recv_len = recvfrom(udp_fd, buffer, BUFFER_SIZE, 0, (struct sockaddr*)&client_addr, &client_len);
if (recv_len == -1) {
perror("UDP recvfrom failed");
exit(EXIT_FAILURE);
}
printf("Received UDP data: %s\n", buffer);
ssize_t send_len = sendto(udp_fd, buffer, recv_len, 0, (struct sockaddr*)&client_addr, client_len);
if (send_len == -1) {
perror("UDP sendto failed");
exit(EXIT_FAILURE);
}
printf("Sent UDP data: %s\n", buffer);
} else {
char buffer[BUFFER_SIZE];
ssize_t recv_len = recv(fd, buffer, BUFFER_SIZE, 0);
if (recv_len <= 0) {
if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL) == -1) {
perror("epoll_ctl for closing TCP connection failed");
exit(EXIT_FAILURE);
}
close(fd);
printf("TCP connection closed.\n");
} else {
printf("Received TCP data: %s\n", buffer);
ssize_t send_len = send(fd, buffer, recv_len, 0);
if (send_len == -1) {
perror("TCP send failed");
exit(EXIT_FAILURE);
}
printf("Sent TCP data: %s\n", buffer);
}
}
}
}
close(server_fd);
close(epoll_fd);
return 0;
}
LINUX下服务器实现
最新推荐文章于 2024-10-17 23:39:11 发布