i want to do a proxy with epoll. but it fail.
i only open one web , but the accept sockfd constantly increase.
then read fail .
i am very confuse for that
#define msglen 1500
#define LISTENQ 20
#define SERV_PORT 7777
#define MAXEVENT 1000
int serverfd,clientfd;
void setNonBlock( int );
int bindlisten();
int clientconn();
main () {
struct sockaddr_in tcpaddr,cliaddr,servaddr;
int retVal,errno,count=0;
char line[msglen]={0};
int tcpaddr_len,lstnScktNum;
fd_set fdset;
int k_milliSecPerSec= 1000,msecWaitTime = 10000;
struct timeval timeout;
int max_fd,fd;
int a[65535]={0},b[65535]={0};
int listenfd,connfd,sockfd,epfd,nfds;
ssize_t n;
socklen_t clilen;
int i;
signal (SIGPIPE,SIG_IGN);
serverfd=bindlisten();
if (serverfd==-1) {
printf("line62:bind & listen fail\n");
return -1 ;
}
struct epoll_event ev, events[20];
epfd=epoll_create(MAXEVENT);
ev.data.fd=serverfd;
ev.events=EPOLLIN|EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_ADD,serverfd,&ev);
while (1) {
nfds=epoll_wait(epfd,events,MAXEVENT,0);
for(i=0; i<nfds;> fd=events[i].data.fd;
if (fd==serverfd)
{
clilen=sizeof(cliaddr);
int connfd =accept(fd, (struct sockaddr *)(&cliaddr), &clilen);
setNonBlock(connfd);
if(connfd > 0){
char *str=inet_ntoa(cliaddr.sin_addr);
if (ret <0) {
return -1;
}
ev.data.fd=connfd;
ev.events=EPOLLIN|EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);
clientfd=clientconn();
setNonBlock(clientfd);
if (clientfd==-1) {
return -1;
}
if(ret<0) {
printf("ret=%d\n",ret);
}
ev.data.fd=clientfd;
ev.events=EPOLLIN|EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_ADD,clientfd,&ev);
a[connfd]=clientfd;
b[clientfd]=connfd;
}
}
else if (events[i].events & EPOLLIN)
{
if((sockfd=events[i].data.fd)<0)
continue;
retVal = recv(sockfd, line, msglen,MSG_NOSIGNAL);
if(retVal <= 0){
if(errno==ECONNRESET) {
close(fd);
epoll_ctl(epfd,EPOLL_CTL_DEL,fd,&ev);
events[i].data.fd=-1;
int temp=a[fd];
a[fd]=0;
b[temp]=0;
temp=b[fd];
b[fd]=0;
a[temp]=0;
} else if(errno!=EAGAIN) {
perror("line143:read error:");
return 1;
}
} else {
if (a[sockfd]!=0) {
fd=a[sockfd];
int ret=send(fd,line,retVal,MSG_NOSIGNAL);
if (ret <0 && errno != EAGAIN) {
perror("write() 1:");
return 1;
} else {
printf("write to proxy:%d\n",fd);
}
} else if (b[sockfd]!=0) {
fd=b[sockfd];
int ret=send(fd,line,retVal,MSG_NOSIGNAL);
if (ret <0 && errno != EAGAIN){
perror("write() 2");
return 1;
} else {
printf("write to user:%d\n",fd);
}
}
memset(line,0x00,msglen);
}
}
else {
fd=events[i].data.fd;
epoll_ctl(epfd, EPOLL_CTL_DEL,fd, &ev);
close (fd);
}
}
}
for(i= 0; i<nfds;> close(events[nfds].data.fd);
epoll_ctl(epfd,EPOLL_CTL_DEL,events[nfds].data.fd,&ev);
events[nfds].data.fd=-1;
}
}
int bindlisten() {
struct sockaddr_in tcpaddr;
struct in_addr intfIpAddr;
int tcpaddr_len;
int sockfd;
int port;
int bReuseaddr=1;
int retVal;
memset( &tcpaddr, 0, sizeof(tcpaddr) );
port=SERV_PORT;
if ( (sockfd= socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
printf ("socket create fail\n");
return -1;
}
setNonBlock(sockfd);
tcpaddr.sin_family = AF_INET;
tcpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
tcpaddr.sin_port = htons(port);
tcpaddr_len = sizeof(tcpaddr);
if ((retVal = bind(sockfd, (struct sockaddr *)(&tcpaddr), sizeof(tcpaddr)))< 0 )
{
fprintf(stdout,"bind() call failed. Error: %d, %s,port: %d\n ", errno, ( strerror(errno) ), port);
}
int optlen;
if (listen(sockfd, 20) < 0 )
{
printf("Error: Listen socket returned %d %s\n", errno, strerror(errno) );
return -1;
}
return sockfd;
}
int clientconn() {
struct sockaddr_in tcpaddr;
char ipHost[10]={0};
int ipPort=8000;
int ret;
int sockfd;
int bReuseaddr=1;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("socket create fail\n");
return -1;
}
memset(&tcpaddr, 0, sizeof(tcpaddr));
strcpy(ipHost, "127.0.0.0");
tcpaddr.sin_family = AF_INET;
tcpaddr.sin_addr.s_addr = inet_addr((const char *)ipHost);
tcpaddr.sin_port = htons(ipPort);
if (ret<0) {
return -1;
}
if ((ret = connect(sockfd,(struct sockaddr *)(&tcpaddr),sizeof(tcpaddr))) < 0 ) {
printf("connect fail,retVal=%d,%s\n",errno,strerror(errno));
return 1;
}
return sockfd;
}
void setNonBlock( int sock_fd )
{
int opts;
opts = fcntl( sock_fd, F_GETFL );
if( opts < 0 )
{
printf("err:fcntl F_GETFL");
exit( 1 );
}
opts = opts | O_NONBLOCK ;
if( fcntl( sock_fd, F_SETFL, opts ) < 0 )
{
printf("err:fcntl F_SETFL");
exit( 1 );
}
}