1. epoll-httpserver
为了深入理解java的reactor模型,用c语言实现一下。
程序结构:
主线程用来接受新的连接
新线程用来处理请求
epoll_http_test.c 源文件
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/epoll.h>
#include<pthread.h>
#include<string.h>
struct epoll_event events[10];
int epollRet;
void* thread_run_wait(void* arg){
while (1){
int ws = epoll_wait(epollRet, events, 10, -1);
printf("wait 返回 %d\n", ws);
if (ws < 0){
perror("epoll_wait");
continue;
}
for (int i = 0; i < ws; ++i) {
//
if(events[i].events == EPOLLIN){
char buf[1024] = {0};
int resSize = recv(events[i].data.fd, buf, 1024, 0);
printf("%s\n", buf);
bzero(&buf, 1024);
char* sendBuf = "HTTP/1.1 200 OK\nContent-Type: text/html;charset=utf-8\nContent-Length: 6\n\nhello\n";
strcpy(buf, sendBuf);
int r = send(events[i].data.fd, &buf, 1024, 0);
}else if (events[i].events == EPOLLERR){
printf("%s\n", "error close clifd");
epoll_ctl(epollRet, EPOLL_CTL_MOD, events[i].data.fd, &events[i]);
close(events[i].data.fd);
}else{
printf("%s\n", "error close clifd");
epoll_ctl(epollRet, EPOLL_CTL_MOD, events[i].data.fd, &events[i]);
close(events[i].data.fd);
}
}
}
}
int main(){
int socketserverfd = socket(AF_INET, SOCK_STREAM, 0);
if (socketserverfd < 0){
perror("socket");
exit(-1);
}
struct sockaddr_in addr;
addr.sin_port = htons(8080);
addr.sin_family = AF_INET;
int bindre = bind(socketserverfd, (struct sockaddr*)&addr, sizeof(addr));
if (bindre < 0){
perror("bind");
exit(-1);
}
int res = listen(socketserverfd, 5);
if (res < 0){
perror("listen");
exit(-1);
}
struct sockaddr_in cli;
int len = sizeof(cli);
epollRet = epoll_create(1024);
pthread_t pt;
int pres = pthread_create(&pt, NULL, thread_run_wait, NULL);
if (pres == -1){
perror("pthread_create");
exit(-1);
}
while (1){
int clifd = accept(socketserverfd, NULL, &len);
printf("新的连接对象 %d\n", clifd);
if (clifd < 0){
perror("accept");
continue;
}
struct epoll_event fdEvent;
fdEvent.events = EPOLLIN|EPOLLERR;
fdEvent.data.fd = clifd;
// 添加
epoll_ctl(epollRet, EPOLL_CTL_ADD, clifd, &fdEvent);
}
return 0;
}
2. 编译
gcc epoll_http_test.c -o epoll_server -l pthread
编译后的文件,这个可以在linux系统运行
3. 启动
./epoll_server
4. 浏览器请求
http://localhost:8080/
后台打印的http请求信息