1 #include <sys/socket.h>
3 #include <netinet/in.h>
4 #include <netinet/tcp.h>
6 #include <sys/sendfile.h>
20 void setnonblocking(int sockfd
) {
23 opts
= fcntl(sockfd
, F_GETFL
);
25 perror("fcntl(F_GETFL)\n");
28 opts
= (opts
| O_NONBLOCK
);
29 if(fcntl(sockfd
, F_SETFL
, opts
) < 0) {
30 perror("fcntl(F_SETFL)\n");
38 struct epoll_event ev
, events
[MAX_EVENTS
];
39 int addrlen
, listenfd
, conn_sock
, nfds
, epfd
, fd
, i
, nread
, n
;
40 struct sockaddr_in local
, remote
;
44 if( (listenfd
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0) {
48 setnonblocking(listenfd
);
49 bzero(&local
, sizeof(local
));
50 local
.sin_family
= AF_INET
;
51 local
.sin_addr
.s_addr
= htonl(INADDR_ANY
);;
52 local
.sin_port
= htons(PORT
);
53 if( bind(listenfd
, (struct sockaddr
*) &local
, sizeof(local
)) < 0) {
59 epfd
= epoll_create(MAX_EVENTS
);
61 perror("epoll_create");
66 ev
.data
.fd
= listenfd
;
67 if (epoll_ctl(epfd
, EPOLL_CTL_ADD
, listenfd
, &ev
) == -1) {
68 perror("epoll_ctl: listen_sock");
73 nfds
= epoll_wait(epfd
, events
, MAX_EVENTS
, -1);
75 perror("epoll_pwait");
79 for (i
= 0; i
< nfds
; ++i
) {
80 fd
= events
[i
].data
.fd
;
83 while ((conn_sock
= accept(listenfd
,(struct sockaddr
*) &remote
,
84 (size_t *)&addrlen
)) > 0) {
85 setnonblocking(conn_sock
);
86 ev
.events
= EPOLLIN
| EPOLLET
;
87 ev
.data
.fd
= conn_sock
;
88 if (epoll_ctl(epfd
, EPOLL_CTL_ADD
, conn_sock
,
90 perror("epoll_ctl: add");
94 if (conn_sock
== -1) {
95 if (errno
!= EAGAIN
&& errno
!= ECONNABORTED
96 && errno
!= EPROTO
&& errno
!= EINTR
)
101 if (events
[i
].events
& EPOLLIN
) {
104 while ((nread
= read(fd
, buf
+ n
, BUFSIZ
-1)) > 0) {
107 if (nread
== -1 && errno
!= EAGAIN
) {
108 perror("read error");
111 ev
.events
= events
[i
].events
| EPOLLOUT
;
112 if (epoll_ctl(epfd
, EPOLL_CTL_MOD
, fd
, &ev
) == -1) {
113 perror("epoll_ctl: mod");
116 if (events
[i
].events
& EPOLLOUT
) {
118 sprintf(buf
, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\nHello World", 11);
119 int nwrite
, data_size
= strlen(buf
);
122 nwrite
= write(fd
, buf
+ data_size
- n
, n
);
124 if (nwrite
== -1 && errno
!= EAGAIN
) {
125 perror("write error");