#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <ctype.h>
//服务器监听端口号
#define PORT 20000
//服务器监听IP
#define IP "127.0.0.1"
//服务器支持的最大连接数
#define MAX_CONNECTION 1024
//用户区字符缓存区大小
#define BUFFSIZE 1024
int main()
{
int listenfd,connfd,sockfd,epfd;//文件描述符
struct sockaddr_in servaddr,clieaddr;//网络地址结构体
socklen_t clieaddr_len=sizeof(clieaddr);//存放客户端地址大小
int ret;//临时变量
struct epoll_event rdevt;//epoll事件
struct epoll_event evts[MAX_CONNECTION];//epoll事件数组,用作epoll_wait的输出
int nready;//用作epoll_wait的返回值
int i,j;//循环因子
char buff[BUFFSIZE],clientip[32];
int num;
listenfd=socket(PF_INET,SOCK_STREAM,0);//创建tcp套接字
if(listenfd<0)
{
perror("socket error");
exit(1);
}
//初始化服务器网络地址结构体,用作bind的参数
memset(&servaddr,'\0',sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(PORT);
inet_pton(AF_INET,IP,&servaddr.sin_addr);
ret=bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));//将listenfd赋予地址和端口
if(ret<0)
{
perror("bind error");
exit(1);
}
ret=listen(listenfd,128);//设置服务器为监听状态
if(ret<0)
{
perror("listen error");
exit(1);
}
epfd=epoll_create(MAX_CONNECTION);//创建epoll实例,并返回对应的文件描述符
if(epfd<0)
{
perror("epoll_create error");
exit(1);
}
//将listenfd赋值给epoll事件
rdevt.events=EPOLLIN;
rdevt.data.fd=listenfd;
//将listenfd添加到epfd中进行监听
ret=epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&rdevt);
if(ret<0)
{
perror("epoll_ctl error");
exit(1);
}
while(1)
{
nready=epoll_wait(epfd,evts,MAX_CONNECTION,-1);//开启监听
for(i=0;i<nready;i++)
{
if((sockfd=evts[i].data.fd)==listenfd)//有新的连接
{
memset(&clieaddr,'\0',sizeof(clieaddr));
connfd=accept(listenfd,(struct sockaddr *)&clieaddr,&clieaddr_len);
printf("An new connection was accepted. IP = %s, PORT = %d\n",
inet_ntop(AF_INET,&clieaddr.sin_addr,clientip,sizeof(clientip)),
ntohs(clieaddr.sin_port));
rdevt.events=EPOLLIN;
rdevt.data.fd=connfd;
ret=epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&rdevt);//将新的连接添加到epfd中进行状态监听
if(ret<0)
{
perror("epoll_ctl error");
close(connfd);
}
continue;
}
num=recv(sockfd,buff,sizeof(buff),0);//读取socket缓存区中的数据
if(num<0)
{
printf("recv error.\n");
} else if(num==0)
{
printf("some client had closed.\n");
close(sockfd);
}else
{
for(j=0;j<num;j++)
{
buff[j]=toupper(buff[j]);
}
send(sockfd,buff,num,0);
}
}
}
}
运行效果:
[zlf@rhel5 day20181226]$ ./epollserver
An new connection was accepted. IP = 127.0.0.1, PORT = 33790
An new connection was accepted. IP = 127.0.0.1, PORT = 33791
An new connection was accepted. IP = 127.0.0.1, PORT = 33792
some client had closed.
some client had closed.
An new connection was accepted. IP = 127.0.0.1, PORT = 33793
An new connection was accepted. IP = 127.0.0.1, PORT = 33794