代理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
");
                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
",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
",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
");
                                return -1;
                        }
                        printf("create a new connect to default proxy: %d
", 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
",i,i,client[i].fd);
                                        break;
                                }
                        if (i==OPEN_MAX)
                                perror("too many clients");
                        printf("line93:i=%d,nready=%d
",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
",i,client[i].fd);
                                memset(line,0x00,MAXLINE);
                                printf("line117:sockfd=%d;nready=%d
",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
");
                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
",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
 ", errno, ( strerror(errno) ), port);
    }

//listen have 5 queue
    if (listen(sockfd, 5) < 0 )
    {
        printf("Error: Listen socket returned %d %s
", 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
");
                return -1;
        }
        printf("line202:sockfd=%d
",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
",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
",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
",fd, fdmap);
                ret=write(fdmap,line,n);
                if (ret <=0) {
                        if (errno!=EINTR) 
                                closemap(fdmap,i);
                } else  
                        printf("write to default proxy
");

        } 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
",fd, fdmap);
                ret=write(fdmap,line,n);

                if (ret <=0) {
                        if (errno!=EINTR) 
                                closemap(fdmap,i);
                } else 
                        printf("write to user
");
        }
}

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
",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
",a[fd]);
                a[fd]=0;
                b[temp]=0;
        } else if (b[fd]!=0) {
                temp=b[fd];
                close(b[fd]);
                printf("server  close %d
",b[fd]);
                b[fd]=0;
                a[temp]=0;
        }

        for (j=1;j<=maxi;j++)
                if (client[j].fd==temp)
                        {
                                client[j].fd=-1;
                                break;
                        }
}

原文地址:https://www.cnblogs.com/claireyuancy/p/6921497.html