#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <strings.h>
void err_quit(char *msg)
{
char buf[1024];
snprintf(buf, sizeof(buf), "%s", msg);
perror(buf);
exit(1);
}
void set_nonblocking(int sfd)
{
int opts;
if ((opts=fcntl(sfd,F_GETFL)) < 0)
err_quit("fcntl get socket flag error");
opts = opts|O_NONBLOCK;
if(fcntl(sfd,F_SETFL,opts)<0)
err_quit("fcntl set socket flag error");
}
#define SERV_PORT 12345
#define SERV_LENSENQ 100
int main(int argc, char *argv[])
{
int fd, listenfd, connfd;
int epfd, nfds;
int i, n;
char wbuf[] = "abcdefghijk";
char rbuf[1024] = {0};
struct sockaddr_in srvaddr, cliaddr;
socklen_t clilen = sizeof(cliaddr);
struct epoll_event ev;
struct epoll_event events[50];
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_quit("socket error");
//set_nonblocking(listenfd);
srvaddr.sin_family = AF_INET;
const char *server_addr = "127.0.0.1";
inet_aton(server_addr, &srvaddr.sin_addr);
srvaddr.sin_port = htons(SERV_PORT);
if (bind(listenfd, (struct sockaddr*)&srvaddr, sizeof(srvaddr)) < 0)
err_quit("bind error");
if (listen(listenfd, SERV_LENSENQ) < 0)
err_quit("listen error");
printf("server listen on %s:%d\n", server_addr, SERV_PORT);
if ((epfd = epoll_create(256)) < 0)
err_quit("epoll_create error");
ev.data.fd = listenfd;
ev.events = EPOLLIN;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev) < 0)
err_quit("epoll_ctl for listenfd error");
for(;;){
nfds = epoll_wait(epfd, events, sizeof(events), 1000);
for (i = 0; i < nfds; i++){
if (events[i].data.fd == listenfd){
printf("listenfd event\n");
connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &clilen);
if (connfd < 0)
err_quit("accept error");
char *str = inet_ntoa(cliaddr.sin_addr);
printf("accept connect from %s\n", str);
ev.data.fd = connfd;
ev.events = EPOLLIN;
epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
}else if(events[i].events & EPOLLIN){
printf("connfd read event\n");
if ((fd = events[i].data.fd) < 0)
continue;
if ((n = read(fd, rbuf, sizeof(rbuf))) < 0){
close(fd);
events[i].data.fd = -1;
printf("read error\n");
} else if (n == 0) {
close(fd);
events[i].data.fd = -1;
}
rbuf[n] = '\0';
printf("server read %d bytes: %s\n", n, rbuf);
ev.data.fd = fd;
ev.events = EPOLLOUT;
epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev);
}else if(events[i].events & EPOLLOUT){
fd = events[i].data.fd;
if ((n = write(fd, wbuf, sizeof(wbuf))) < 0){
close(fd);
events[i].data.fd = -1;
printf("write error");
}
printf("server write data: '%s' to client\n", wbuf);
ev.data.fd = fd;
ev.events = EPOLLIN;
epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev);
}
}
}//end for(;;)
close(epfd);
return 0;
}
|