代理服务器 poll version

 poll和select一样,管理多个描述符也是进行轮询,根据描述符的状态进行处理,但是poll没有最大文件描述符数量的限制,select is 1024/2048.

姊妹篇:代理服务器select version https://blog.csdn.net/fdsafwagdagadg6576/article/details/40891823.

代理服务器多线程版 1:https://blog.csdn.net/fdsafwagdagadg6576/article/details/42872279.

多线程代理服务器version2:https://blog.csdn.net/fdsafwagdagadg6576/article/details/42872371.

#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 proxy[65535]={0},user[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("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("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("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
                                        break;
                                }
                        if (i==OPEN_MAX)
                                perror("too many clients");
                        client[i].events=POLLIN;

                        if(i>maxi)
                                maxi=i; //max index in client[] array
                        //map user and default proxy socket
                        proxy[connfd]=clientfd;
                        user[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)) {
                                memset(line,0x00,MAXLINE);
                                if((n=read(sockfd,line,MAXLINE)) <=0) {
                                        if (errno==EINTR)  {
                                                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;
        }
        /* 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);
//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 (proxy[fd]!=0) {
                fdmap=proxy[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 (user[fd]!=0) {
                fdmap=user[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");
        }
}
//remove proxy and user socket fd together
void closemap (int fd,int i) {
        int temp;
        int j;
        //The socket is wrong or closed.
        close(fd);
        client[i].fd=-1;
        if (proxy[fd]!=0) {
                temp=proxy[fd];
                close (proxy[fd]);
                printf("client close %d\n",proxy[fd]);
                proxy[fd]=0;
                user[temp]=0;
        } else if (user[fd]!=0) {
                temp=user[fd];
                close(user[fd]);
                printf("server  close %d\n",user[fd]);
                user[fd]=0;
                proxy[temp]=0;
        }

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值