使用EPOLL实现简单的服务端sock程序
//使用epoll模型开发服务端流程
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <pthread.h>
#include <errno.h>
#include <sys/socket.h>
#include <poll.h>
#include <sys/epoll.h>
#include <ctype.h>
#include "wrap.h"
#define PROT 7755
int main()
{
int lfd = Socket(AF_INET,SOCK_STREAM,0);
//设置端口复用
int opt = 1;
setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
struct sockaddr_in serv;
serv.sin_family = AF_INET;
serv.sin_port = htons(PROT);
serv.sin_addr.s_addr = htonl(INADDR_ANY);
printf("BIND\n");
Bind(lfd,(struct sockaddr*)&serv,sizeof(serv));
printf("LISTEN\n");
Listen(lfd,128);
int nready;
int cfd;
struct sockaddr_in client;
socklen_t client_len = sizeof(client);
char buf[1024];
int n = 0;
printf("EPOLL 结构体\n");
//创建epoll结构体
struct epoll_event ev;
ev.data.fd = lfd;
ev.events = EPOLLIN;
struct epoll_event events[1024];
printf("EPOLL 树\n");
//创建一课EPOLL树
int epfd = epoll_create(1024);
if(epfd < 0)
{
perror("create epoll error\n");
return -1;
}
//将监听文件描述符添加到树里面去
epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &ev);
printf("EPOLL 循环\n");
while(1)
{
printf("EPOLL WAIT\n");
nready = epoll_wait(epfd,events,1024,-1);
if(nready < 0)
{
if(errno == EINTR)//被信号中断
{
printf("信号中断!\n");
continue;
}
break;
}
int k = 0;
printf("EPOLL 处理\n");
for(;k < nready; ++k)
{
//监听事件
printf("EPOLL LISTEN\n");
if(events[k].data.fd == lfd)
{
cfd = Accept(lfd,NULL,NULL);
ev.data.fd = cfd;
ev.events = EPOLLIN;
epoll_ctl(epfd,EPOLL_CTL_ADD,cfd,&ev);
}
else//读取数据
{
printf("EPOLL READ\n");
int sockfd = events[k].data.fd;
memset(buf,0x00,sizeof(buf));
n = Read(sockfd,buf,sizeof(buf));
if(n <= 0){
printf("read error or client closed!\n");
Close(sockfd);
//将树上的事件删除
epoll_ctl(epfd,EPOLL_CTL_DEL,sockfd,NULL);
}
else
{
printf("buf==[%s],n==[%d]\n",buf,n);
int p = 0;
for(;p < n; ++p)
{
buf[p] = toupper(buf[p]);
}
Write(sockfd,buf,n);
}
}
}
}
Close(epfd);
Close(lfd);
return 0;
}