#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#define MAX_EVENTS 10 //epoll支持的最大事件数
#define BUFFER_SIZE 1024//缓冲区大小
int main(int argc,const char *argv[])
{
int server_fd,client_fd,epoll_fd,event_count,i;
struct sockaddr_in server_addr,client_addr;
socklen_t client_addr_len;
struct epoll_event event,events[MAX_EVENTS];
char buffer[BUFFER_SIZE];
//创建监听套接字
server_fd = socket(AF_INET,SOCK_STREAM,0);//创建socket函数套接字
if(server_fd == -1)
{
perror("socket");
exit(EXIT_FAILURE);
}
//设置服务器地址
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;//INADDR_ANY代表接收全部ip地址的链接请求
server_addr.sin_port = htons(8080);//设置监听端口
//绑定套接字到服务器地址
if(bind(server_fd,(struct sockaddr*)&server_addr,sizeof(server_addr)) == -1)
{
perror("bind");
exit("EXIT_FAILURE");
}
//监听链接
if(listen(server_fd,5) == -1)
{
perror("listen");
exit("EXIT_FAILURE");
}
//添加监听套接字到epoll
event.events = EPOLLIN;
event.data.fd = server_fd;
if(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,server_fd,&event) == -1)
{
perror("epoll_ctl");
exit("EXIT_FAILURE");
}
while(1)
{
//等待事件发生
event_count = epoll_wait(epoll_fd,events,MAX_EVENTS,-1);
if(event_count == -1)
{
perror("epoll_wait");
exit("EXIT_FAILURE");
}
//处理事件
for(i =0;i<event_count;i++)
{
if(events[i].data.fd == server_fd)
{
//接收新的连接
client_addr_len = sizeof(client_addr);
client_fd = accept(server_fd,(struct sockaddr*)&client_addr,&client_addr_len);
if(client_fd == -1)
{
perror("accept");
exit("EXIT_FAILURE");
}
//将新的连接添加到epoll
event.events = EPOLLIN;
event.data.fd = client_fd;
if(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,client_fd,&event)==-1)
{
perror("epoll_ctl");
exit("EXIT_FAILURE");
}
else
{
//处理客户端请求
client_fd = events[i].data.fd;
memset(buffer,0,BUFFER_SIZE);
int recv_size = recv(client_fd,buffer,BUFFER_SIZE,0);
if(recv_size == -1)
{
perror("recv");
exit("EXIT_FAILURE");
}
else if(recv_size == 0)
{
//客户端断开连接
printf("断开连接\n");
epoll_ctl(epoll_fd,EPOLL_CTL_DEL,client_fd,NULL);
close(client_fd);
}
else
{
//回复客户端
printf("received message :%s\n",buffer);
const char* response = "Hello,client";
if(send(client_fd,response,strlen(response),0)==-1)
{
perror("send");
exit("EXIT_FAILURE");
}
}
}
}
}
//关闭监听套接字和epoll
close(server_fd);
close(epoll_fd);
}
return 0;
}
用epoll实现并发服务器
最新推荐文章于 2024-07-19 17:46:34 发布
该代码示例展示了如何在Linux上使用epoll进行IO多路复用,创建一个服务器监听8080端口,接受客户端连接,并处理客户端请求。epoll_ctl用于管理epoll事件,epoll_wait等待并处理发生的事件。
摘要由CSDN通过智能技术生成