/*************************************************************************
> File Name: epoll_serve.c
> Author: xuhcen_allen
> Mail: xuchen_allen@
> Created Time: 02月14日 星期四 09时08分16秒
************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PORT 8080
int main()
{
struct sockaddr_in serv_addr,cli_addr;
socklen_t serv_len = sizeof(serv_addr);
socklen_t cli_len = sizeof(cli_addr);
//创建监听套接字:
int lfd = socket(AF_INET,SOCK_STREAM,0);
memset(&serv_addr,0,serv_len);
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port=htons(PORT);
//绑定IP和端口:
bind(lfd,(struct sockaddr*)&serv_addr,serv_len);
//设置同时监听最大个数:
listen(lfd,36);
printf("Waiting for connecting...\n");
//创建epoll根结点:
int epfd = epoll_create(1000);//epoll_creat中的参数现在意义不大;
//初始化epoll树:
struct epoll_event ev;//创建一个事件:
ev.events = EPOLLIN;
ev.data.fd = lfd;
epoll_ctl(epfd,EPOLL_CTL_ADD,lfd,&ev);//将事件挂在树上,相当于初始化epoll树;
struct epoll_event all[2000];//用数组储存这些事件,方便挂树,查询;
while(1){
//使用epoll通知内核fd 文件IO检测;
int ret = epoll_wait(epfd,all,sizeof(all)/sizeof(all[0]),-1);//将检测到的epfd放到事件数组all中;
//返回值是数组中准备就绪的事件数;
//遍历all数组中的前ret个元素:
for(int i = 0;i
int fd = all[i].data.fd;
//提取出数组元素的fd,判断是否有连接:
if(fd == lfd){//这个if判断是判断用于监听的lfd是否加入到了ret中,如果加入了,就说明有新的连接;
int cfd = accept(lfd,(struct sockaddr*)&cli_addr,&cli_len);
if(cfd<0){
perror("accept error");
exit(1);
}
//将新得到的cfd挂到树上:
struct epoll_event temp;
temp.events = EPOLLIN;
temp.data.fd = cfd;
epoll_ctl(epfd,EPOLL_CTL_ADD,cfd,&temp);
//打印客户端信息:
char ip[64];
printf("New Client IP:%s ,\t Port:%d\n",inet_ntop(AF_INET,&cli_addr.sin_addr.s_addr,ip,sizeof(ip)) ,ntohs(cli_addr.sin_port));
}
else{
//处理已经连接的客户端发送过来的数据:
if(!all[i].events & EPOLLIN){
continue ;
}
//读数据:
char buf[1024];
int len = recv(fd,buf,sizeof(buf),0);
if(len<0){
perror("recv fail");
exit(1);
}
else if(len==0){
printf(" client disconnecting...\n ");
close(fd);
//fd从epoll树中取下来:
epoll_ctl(epfd,EPOLL_CTL_DEL,fd,NULL);
}
else{
printf( "recv success:\n");
write(STDOUT_FILENO,buf,len);
}
}
}
}
close(lfd);
return 0;
}
如果觉得《linux并发服务器实例 linux-----网络编程----epoll实现并发服务器》对你有帮助,请点赞、收藏,并留下你的观点哦!