#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "sys/socket.h"
#include "netinet/in.h"
#include "sys/epoll.h"
#include "fcntl.h"
#include "sys/ioctl.h"
#include "errno.h"
void setnonblocking(int sock)
{
if(fcntl(sock,F_SETFL,O_NONBLOCK)<0)
{
printf("fcntl set error1\n");exit(1);
}
}
int main()
{
int len,nfds,opts,epfd,listenfd,client,sockfd;
char buf[10],last[5000];
struct sockaddr_in server_addr,client_addr;
struct epoll_event ev,events[20];
listenfd=socket(AF_INET,SOCK_STREAM,0);
setnonblocking(listenfd);
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(7878);
server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,1,sizeof(int));
bind(listenfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
listen(listenfd,20);
epfd=epoll_create(256);
ev.data.fd=listenfd;
ev.events=EPOLLIN|EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);
int i,maxi=0;
for(;;)
{
nfds=epoll_wait(epfd,events,20,500);
for(i=0;i<nfds;i++)
{
if(events[i].data.fd == listenfd)
{
socklen_t client_size=sizeof(client_addr);
client=accept(listenfd,(struct sockaddr *)&client_addr,&client_size);
if(client <0)
{
printf("client accept error\n");exit(1);
}
setnonblocking(client);
ev.data.fd=client;
ev.events=EPOLLIN|EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_ADD,client,&ev);
}
else{
if(events[i].events == EPOLLIN)
{
//read data
len=0;
int n,readsock,read_num;
if((readsock=events[i].data.fd)<0) continue;
ioctl(readsock,FIONREAD,&read_num);
printf("we will get %d char\n",read_num);
while(len < read_num)
{
if((n=read(readsock,buf,10))<0)
{
if(errno == ECONNRESET)
{
close(readsock);
ev.data.fd=readsock;
ev.events=EPOLLIN|EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_DEL,readsock,&ev);
break;
}
else if(errno == EAGAIN){
break;
}
}
else if(n == 0)
{
close(readsock);
ev.data.fd=readsock;
ev.events=EPOLLIN|EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_DEL,readsock,&ev);
break;
}
buf[n]='\0';
len=len+n;
strcat(last,buf);
}
ev.data.fd=readsock;
ev.events=EPOLLOUT|EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_MOD,readsock,&ev); //change mode from read to write
}
if(events[i].events == EPOLLOUT)
{
//write data
int writesock=events[i].data.fd;
write(writesock,last,len);
ev.data.fd=writesock;
ev.events=EPOLLIN|EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_DEL,writesock,&ev);
close(writesock);
bzero(last,sizeof(last));
}
}
}
}
}