c语言 libevent高并发http代码
时间: 2023-09-24 11:03:03 浏览: 62
以下是一个基于libevent实现的高并发HTTP服务器的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <event.h>
#define SERVER_PORT 8080
#define BACKLOG 128
void on_accept(int fd, short event, void *arg);
void on_read(int fd, short event, void *arg);
void on_write(int fd, short event, void *arg);
int main(int argc, char *argv[]) {
int server_fd, client_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
// 创建服务器socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
// 设置socket选项
int optval = 1;
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
// 绑定端口
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind");
exit(EXIT_FAILURE);
}
// 监听端口
if (listen(server_fd, BACKLOG) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
// 设置非阻塞
if (fcntl(server_fd, F_SETFL, fcntl(server_fd, F_GETFL) | O_NONBLOCK) < 0) {
perror("fcntl");
exit(EXIT_FAILURE);
}
// 创建event_base
struct event_base *base = event_base_new();
// 创建listen_event
struct event *listen_event = event_new(base, server_fd, EV_READ | EV_PERSIST, on_accept, (void *)base);
event_add(listen_event, NULL);
printf("Server started on port %d\n", SERVER_PORT);
// 进入事件循环
event_base_dispatch(base);
// 清理资源
event_free(listen_event);
event_base_free(base);
close(server_fd);
return 0;
}
void on_accept(int fd, short event, void *arg) {
struct event_base *base = (struct event_base *)arg;
while ((client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len)) > 0) {
// 设置非阻塞
if (fcntl(client_fd, F_SETFL, fcntl(client_fd, F_GETFL) | O_NONBLOCK) < 0) {
perror("fcntl");
exit(EXIT_FAILURE);
}
// 创建read_event
struct event *read_event = event_new(base, client_fd, EV_READ | EV_PERSIST, on_read, NULL);
event_add(read_event, NULL);
}
}
void on_read(int fd, short event, void *arg) {
char buffer[4096];
int n = read(fd, buffer, sizeof(buffer));
if (n < 0) {
perror("read");
exit(EXIT_FAILURE);
} else if (n == 0) {
// 对端关闭连接
close(fd);
event_del((struct event *)arg);
event_free((struct event *)arg);
} else {
// 创建write_event
struct event *write_event = event_new((struct event_base *)arg, fd, EV_WRITE, on_write, NULL);
event_add(write_event, NULL);
}
}
void on_write(int fd, short event, void *arg) {
char response[] = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World!";
int n = write(fd, response, sizeof(response));
if (n < 0) {
perror("write");
exit(EXIT_FAILURE);
} else {
close(fd);
event_del((struct event *)arg);
event_free((struct event *)arg);
}
}
```
代码实现了一个简单的HTTP服务器,使用了libevent库提供的事件驱动模型,能够同时处理多个客户端请求。当有新的客户端连接到达时,on_accept函数会创建一个新的事件处理器,处理客户端的读写事件。当有数据可读时,on_read函数会创建一个新的事件处理器,处理客户端的写事件。当数据发送完毕时,on_write函数会关闭连接并释放事件处理器。
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)