Created
August 21, 2018 08:42
-
-
Save luw2007/15818cae3fae7ad5fcac482c663d5b63 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//http://www.it165.net/os/html/201308/5868.html | |
#include <sys/socket.h> | |
#include <sys/wait.h> | |
#include <netinet/in.h> | |
#include <netinet/tcp.h> | |
#include <sys/epoll.h> | |
#include <sys/sendfile.h> | |
#include <sys/stat.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <strings.h> | |
#include <fcntl.h> | |
#include <errno.h> | |
#define MAX_EVENTS 10 | |
#define PORT 8888 | |
//设置socket连接为非阻塞模式 | |
void setnonblocking(int sockfd) { | |
int opts; | |
opts = fcntl(sockfd, F_GETFL); | |
if(opts < 0) { | |
perror("fcntl(F_GETFL)\n"); | |
exit(1); | |
} | |
opts = (opts | O_NONBLOCK); | |
if(fcntl(sockfd, F_SETFL, opts) < 0) { | |
perror("fcntl(F_SETFL)\n"); | |
exit(1); | |
} | |
} | |
int main(){ | |
struct epoll_event ev, events[MAX_EVENTS]; | |
int addrlen, listenfd, conn_sock, nfds, epfd, fd, i, nread, n; | |
struct sockaddr_in local, remote; | |
char buf[BUFSIZ]; | |
//创建listen socket | |
if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { | |
perror("sockfd\n"); | |
exit(1); | |
} | |
setnonblocking(listenfd); | |
bzero(&local, sizeof(local)); | |
local.sin_family = AF_INET; | |
local.sin_addr.s_addr = htonl(INADDR_ANY);; | |
local.sin_port = htons(PORT); | |
if( bind(listenfd, (struct sockaddr *) &local, sizeof(local)) < 0) { | |
perror("bind\n"); | |
exit(1); | |
} | |
listen(listenfd, 20); | |
epfd = epoll_create(MAX_EVENTS); | |
if (epfd == -1) { | |
perror("epoll_create"); | |
exit(EXIT_FAILURE); | |
} | |
ev.events = EPOLLIN; | |
ev.data.fd = listenfd; | |
if (epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev) == -1) { | |
perror("epoll_ctl: listen_sock"); | |
exit(EXIT_FAILURE); | |
} | |
for (;;) { | |
nfds = epoll_wait(epfd, events, MAX_EVENTS, -1); | |
if (nfds == -1) { | |
perror("epoll_pwait"); | |
exit(EXIT_FAILURE); | |
} | |
for (i = 0; i < nfds; ++i) { | |
fd = events[i].data.fd; | |
if (fd == listenfd) { | |
while ((conn_sock = accept(listenfd,(struct sockaddr *) &remote,(size_t *)&addrlen)) > 0) { | |
setnonblocking(conn_sock); //设置连接socket为非阻塞 | |
ev.events = EPOLLIN | EPOLLET; //边沿触发要求套接字为非阻塞模式;水平触发可以是阻塞或非阻塞模式 | |
ev.data.fd = conn_sock; | |
if (epoll_ctl(epfd, EPOLL_CTL_ADD, conn_sock,&ev) == -1) { | |
perror("epoll_ctl: add"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
if (conn_sock == -1) { | |
if (errno != EAGAIN && errno != ECONNABORTED && errno != EPROTO && errno != EINTR) | |
perror("accept"); | |
} | |
continue; | |
} | |
if (events[i].events & EPOLLIN) { | |
n = 0; | |
while ((nread = read(fd, buf + n, BUFSIZ-1)) > 0) { | |
n += nread; | |
} | |
if (nread == -1 && errno != EAGAIN) { | |
perror("read error"); | |
} | |
ev.data.fd = fd; | |
ev.events = events[i].events | EPOLLOUT; | |
if (epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev) == -1) { | |
perror("epoll_ctl: mod"); | |
} | |
} | |
if (events[i].events & EPOLLOUT) { | |
sprintf(buf, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\nHello World", 11); | |
int nwrite, data_size = strlen(buf); | |
n = data_size; | |
while (n > 0) { | |
nwrite = write(fd, buf + data_size - n, n); | |
if (nwrite < n) { | |
if (nwrite == -1 && errno != EAGAIN) { | |
perror("write error"); | |
} | |
break; | |
} | |
n -= nwrite; | |
} | |
close(fd); | |
} | |
} | |
} | |
close(epfd); | |
close(listenfd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment