首页 > 代码库 > 代理server poll version
代理server poll version
poll和select一样,管理多个描写叙述符也是进行轮询,依据描写叙述符的状态进行处理,可是poll没有最大文件描写叙述符数量的限制,select is 1024/2048
#include "stdio.h" #include "stdlib.h" #include "sys/socket.h" #include "netinet/in.h" #include "netinet/tcp.h" #include "arpa/inet.h" #include "string.h" #include <errno.h> #include "sys/time.h" #include "sys/times.h" #include <unistd.h> #include "sys/types.h" #include "poll.h" #include "sys/stropts.h" #include <signal.h> #include <time.h> #define OPEN_MAX 1024 #define MAXLINE 1024 int serverfd,clientfd; int bindlisten(); int clientconn(); void closemap(int sockfd,int i); void writeproxy(int i,int n); int a[65535]={0},b[65535]={0}; char line[MAXLINE]={0}; struct pollfd client[OPEN_MAX]; int maxi; int main (int argc ,char **argv) { int i,listenfd,connfd,sockfd; int nready; ssize_t n; socklen_t clilen; struct sockaddr_in cliaddr; int timeout = 1000; int on; signal (SIGPIPE,SIG_IGN); listenfd=bindlisten(); if (listenfd==-1) { printf("line46:bind & listen fail\n"); return -1 ; } client[0].fd=listenfd; client[0].events=POLLIN; for (i=1;i<OPEN_MAX;i++) client[i].fd=-1; maxi=0;//max index into client[] array for ( ; ; ) { nready=poll(client,maxi+1,timeout); if (client[0].revents & POLLIN) { //new client connection clilen=sizeof(cliaddr); connfd=accept(listenfd,(struct sockaddr *)&cliaddr,&clilen); if (connfd>0) { printf("Accept a new connection:connfd=%d\n",connfd); for(i=1;i<OPEN_MAX;i++) if(client[i].fd<0) { client[i].fd=connfd;//save descriptor printf("line68:i=%d,client[i].fd=%d\n",i,client[i].fd); break; } if (i==OPEN_MAX) perror("too many clients"); client[i].events=POLLIN; if(i>maxi) maxi=i; //max index in client[] array clientfd=clientconn(); if (clientfd==-1) { printf("line98:clientfd fail\n"); return -1; } printf("create a new connect to default proxy: %d\n", clientfd); for(i=1;i<OPEN_MAX;i++) if(client[i].fd<0) { client[i].fd=clientfd;//save descriptor printf("line55:i=%d,client[%d].fd=%d\n",i,i,client[i].fd); break; } if (i==OPEN_MAX) perror("too many clients"); printf("line93:i=%d,nready=%d\n",i,nready); client[i].events=POLLIN; if(i>maxi) maxi=i; //max index in client[] array //map user and default proxy socket //a keep default proxy,b keep user a[connfd]=clientfd; b[clientfd]=connfd; } else perror("accept"); if (--nready<=0) continue; //no more readable descriptors } for (i=1;i<=maxi;i++) { sockfd=client[i].fd; if(sockfd<0) continue; if (client[i].revents &(POLLIN | POLLERR)) { printf("line116:i=%d;fd=%d\n",i,client[i].fd); memset(line,0x00,MAXLINE); printf("line117:sockfd=%d;nready=%d\n",sockfd,nready); if((n=read(sockfd,line,MAXLINE)) <=0) { if (errno==EINTR) { //don;t remove the socket continue; } else { closemap(sockfd,i); } } else writeproxy(i,n); if (--nready<0) break; //no more readable descriptors } } } } int bindlisten() { struct sockaddr_in tcpaddr; struct in_addr intfIpAddr; int tcpaddr_len; int sockfd; int client; int port=8888; int bReuseaddr=1; int retVal; int ret; int buf,optlen; int on,errno; memset( &tcpaddr, 0, sizeof(tcpaddr) ); if ( (sockfd= socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { printf ("socket create fail\n"); return -1; } // intitalize to hold given restrictions tcpaddr.sin_family = AF_INET; tcpaddr.sin_addr.s_addr = htonl(INADDR_ANY); tcpaddr.sin_port = htons(port); tcpaddr_len = sizeof(tcpaddr); on=1; errno=0; if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(char *)(&on),sizeof(on))<0) { printf("so_resueadd failed,error %d:%s\n",errno,strerror(errno)); return -2; } // make bind call if ((retVal = bind(sockfd, (struct sockaddr *)(&tcpaddr), sizeof(tcpaddr)))< 0 ) { printf("bind() call failed. Error: %d, %s,port: %d\n ", errno, ( strerror(errno) ), port); } //listen have 5 queue if (listen(sockfd, 5) < 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; } printf("line202:sockfd=%d\n",sockfd); /* Connect to the socket */ memset(&tcpaddr, 0, sizeof(tcpaddr)); //135.245.1.1 is default default proxy proxy ip strcpy(ipHost, "135.245.1.1"); /* local host, processes must be running on the same machine ... */ /* intitalize to given address */ tcpaddr.sin_family = AF_INET; tcpaddr.sin_addr.s_addr = inet_addr((const char *)ipHost); tcpaddr.sin_port = htons(ipPort); printf("line212:sockfd=%d\n",sockfd); //basic connect is block, after timeout it return fail 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 writeproxy(int i,int n) { int fdmap; int ret; int fd; fd=client[i].fd; if (a[fd]!=0) { fdmap=a[fd]; // if is in a, it come from default proxy,so write to user //forward message to ;ucent printf("Write 1:from %d to %d\n",fd, fdmap); ret=write(fdmap,line,n); if (ret <=0) { if (errno!=EINTR) closemap(fdmap,i); } else printf("write to default proxy\n"); } else if (b[fd]!=0) { fdmap=b[fd]; //is in b, it come from user //forward message to user printf("Write 2 from %d to %d\n",fd, fdmap); ret=write(fdmap,line,n); if (ret <=0) { if (errno!=EINTR) closemap(fdmap,i); } else printf("write to user\n"); } } void closemap (int fd,int i) { int temp; int j; //The socket is wrong or closed. close(fd); client[i].fd=-1; printf("line260 :close %d\n",fd); //remove the socketfd //don;t judge from user or default proxy ,set all kind to 0 //one sockfd close ,peer sockfd close if (a[fd]!=0) { temp=a[fd]; close (a[fd]); printf("client close %d\n",a[fd]); a[fd]=0; b[temp]=0; } else if (b[fd]!=0) { temp=b[fd]; close(b[fd]); printf("server close %d\n",b[fd]); b[fd]=0; a[temp]=0; } for (j=1;j<=maxi;j++) if (client[j].fd==temp) { client[j].fd=-1; break; } }
代理server poll version
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。