#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include < string.h> #include <fcntl.h> #include <stdlib.h> #include <sys/epoll.h> #include <pthread.h > #define Max_event_number 1024#define tcp_buffer_size 512#define udp_buffer_size 1024int setnonblocking (int fd) {i NT old_option = fcntl (fd, F_GETFL); int new_option = Old_option | O_nonblock; Fcntl (FD, F_SETFL, new_option); return old_option;} void addfd (int epollfd, int fd) {struct epoll_event event; EVENT.DATA.FD = FD; event.events = Epollin | Epollet; Event.events = Epollin; Epoll_ctl (EPOLLFD, Epoll_ctl_add, FD, &event); Setnonblocking (FD);} int main (int argc, char* argv[]) {const char* IP = "127.0.01"; int port = 12345; int i=0; int ret = 0; struct SOCKADDR_IN address; Bzero (&addRess, sizeof (address)); address.sin_family = af_inet; Inet_pton (Af_inet, IP, &address.sin_addr); Address.sin_port = htons (port); int LISTENFD = socket (pf_inet, sock_stream, 0); ASSERT (LISTENFD >= 0); ret = bind (LISTENFD, (struct sockaddr*) &address, sizeof (address)); ASSERT (Ret! =-1); RET = Listen (LISTENFD, 5); ASSERT (Ret! =-1); Bzero (&address, sizeof (address)); address.sin_family = af_inet; Inet_pton (Af_inet, IP, &address.sin_addr); Address.sin_port = htons (port); int UDPFD = socket (pf_inet, SOCK_DGRAM, 0); ASSERT (UDPFD >= 0); ret = bind (UDPFD, (struct sockaddr*) &address, sizeof (address)); ASSERT (Ret! =-1); struct epoll_event events[Max_event_number]; int EPOLLFD = epoll_create (5); ASSERT (EPOLLFD! =-1); ADDFD (EPOLLFD, LISTENFD); ADDFD (EPOLLFD, UDPFD); while (1) {int number = Epoll_wait (EPOLLFD, Events, Max_event_number, 1 ); if (number < 0) {printf ("Epoll failure\n"); Break } for (i = 0; i < number; i++) {int sockfd = EVENTS[I].DATA.FD; if (sockfd = = listenfd) {struct sockaddr_in client_address; socklen_t client_addrlength = sizeof (client_address); int CONNFD = Accept (LISTENFD, (struct sockaddr*) &client_address, &client_addrlength); ADDFD (EPOLLFD, CONNFD); } else if (sockfd = = udpfd) {char buf[udp_buffer_size]; memset (buf, ' udp_buffer_size '); struct sockaddr_in client_address; socklen_t client_addrlength = sizeof (client_address); ret = Recvfrom (UDPFD, buf, udp_buffer_size-1, 0, (struct sockaddr*) &client_address, &client_addrlength); if (Ret > 0) { SendTo (UDPFD, buf, udp_buffer_size-1, 0, (struct sockaddr*) &client_address, client_addrlength); }} else if (Events[i].events & Epollin) {char buf[Tcp_buff Er_size]; while (1) {memset (buf, ' n ', tcp_buffer_size); ret = recv (SOCKFD, buf, tcp_buffer_size-1, 0); if (Ret < 0) {if (errno = = Eagain) | | (errno = = Ewouldblock)) {break; } close (SOCKFD); Break } else if (ret = = 0) {close (SOCKFD); } else {Send (SOCKFD, buf, ret, 0); } } } else {printf ("something else happened \ n"); }}} close (LISTENFD); return 0;}
A back-up server that uses the Epoll function to process both TCP requests and UDP requests under Linux