zoukankan      html  css  js  c++  java
  • 代理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;
                            }
    }

  • 相关阅读:
    vscode圣诞帽
    阿里java代码检测工具p3c
    elasticsearch 二、elasticsearch-head安装
    elasticsearch 一、环境配置
    针对json的查询--alibaba的开源项目jsonq
    macos下golang 1.9配置
    此请求已被阻止,因为当用在 GET 请求中时,会将敏感信息透漏给第三方网站。若要允许 GET 请求,请将 JsonRequestBehavior 设置为 AllowGet。
    mvc webapi路由重写
    《Java编程的逻辑》终于上市了!
    《Java编程的逻辑》
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6921497.html
Copyright © 2011-2022 走看看