#include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/epoll.h> #include <netinet/in.h> #include <pthread.h> #include <stdlib.h>
#define SERV_PORT 5358 #define MAX_CONN 1024 #define EVENT_NUM 1024 #define EPOLL_SIZE 1024 #define BUF_LEN 1024
int setnonblocking(int fd){ int opts; if((opts = fcntl(fd, F_GETFL)) < 0){ return -1; } opts |=O_NONBLOCK; if(fcntl(fd, F_SETFL, opts) < 0){ return -1; } return 0; }
void *str_echo(void *arg){ int sockfd; ssize_t nread; char buf[BUF_LEN] = {0}; pthread_detach(pthread_self());
sockfd = *(int *)arg; while(1) { bzero(buf, BUF_LEN); if((nread = read(sockfd, buf, BUF_LEN)) == -1) { if(errno == EINTR) { continue; } else { printf("read error: %s\n", strerror(errno)); continue; } } else if (nread == 0) { break; } else { //fputs(buf, stdout);
write(sockfd, buf, nread); } } return NULL; }
int main(int argc, char **argv) { int listenfd, connfd, epfd, nfds; socklen_t addrlen; struct sockaddr_in cliaddr, servaddr; struct epoll_event ev, events[EVENT_NUM]; pthread_t tid;
//create socket fd
if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ printf("Create socket error!\n"); return 0; } if (setnonblocking(listenfd) == -1){ printf("setnonblicking error!\n"); close(listenfd); return 0; }
//bind
memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1){ printf("Socket bind error!\n"); close(listenfd); return 0; }
//listen
if(listen(listenfd, MAX_CONN) == -1){ printf("listen error\n"); close(listenfd); return 0; }
//create epoll
if((epfd = epoll_create(EPOLL_SIZE)) == -1){ printf("Create epoll error!\n"); close(listenfd); return 0; }
//register epoll event
ev.data.fd = listenfd; ev.events = EPOLLIN | EPOLLET; if ((epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev)) == -1){ printf("epoll_ctl error!\n"); close(listenfd); return 0; }
while(1){ if((nfds = epoll_wait(epfd, events, EVENT_NUM, -1)) ==-1){ if(errno == EINTR){ printf("%s\n", strerror(errno)); continue; } else{ printf("epoll_wait error!\n"); continue; } } int i; for(i=0;i<nfds;i++){ if(events[i].data.fd == listenfd){ addrlen = sizeof(cliaddr); connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &addrlen); if(connfd == -1){ printf("%s\n", strerror(errno)); continue; } printf("New Connection %d\n", connfd); ev.data.fd = connfd; ev.events = EPOLLIN | EPOLLET; if((epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev)) == -1){ printf("connect failed!\n"); } } else{ if((pthread_create(&tid, NULL, str_echo, &events[i].data.fd)) == -1) { exit(0); } } }
} return 0; }
|