socket转发程序

来源:互联网 发布:网络买卖 编辑:程序博客网 时间:2024/05/21 07:56
#include <pthread.h> 
#include <openssl/x509v3.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h> 
#include <sys/wait.h> 
#include <string.h> 
#include <semaphore.h> 
#include <netdb.h> 
#include <unistd.h> 
#include <arpa/inet.h> 


#define MAXSIZE     65535    //最大接收和发送字节 


#define uint16      unsigned short 
#define uint8       unsigned char 
#define uint32      unsigned int 


#define PERROR { printf("%s:%d:%s(): Error: %s\n", __FILE__,__LINE__, __FUNCTION__, strerror( errno ) ); } 
#define EXIT_PERROR { printf("%s:%d:%s(): Error: %s\n", __FILE__,__LINE__, __FUNCTION__, strerror( errno ) ); exit(errno); } 
#define CONTINUE_PERROR { printf("%s:%d:%s(): Error: %s\n", __FILE__,__LINE__, __FUNCTION__, strerror( errno ) ); continue; } 
#define BREAK_PERROR { printf("%s:%d:%s(): Error: %s\n", __FILE__,__LINE__, __FUNCTION__, strerror( errno ) ); break; } 
#define RETURN_PERROR(X) { printf("%s:%d:%s(): Error: %s\n", __FILE__,__LINE__, __FUNCTION__, strerror( errno ) ); return (X); } 


#define max(x,y)            ((x>y) ? x:y) 


static unsigned int packet_count = 0; 


void init_signal() 

    int i=0; 
    for(i; i<=64; i++){ 
        signal( i, SIG_IGN ); 
    } 



void init_daemon(){ 
    if( fork() != 0 ){ 
        exit(0); 
    } 
    setsid(); 
    if( fork() != 0 ){ 
        exit(0); 
    } 



void set_keepalive(int fd) 

        int val = 1; 
        int nRet = setsockopt(fd,SOL_SOCKET,SO_KEEPALIVE,&val,sizeof(val)); 
        if(nRet < 0) { 
                perror( strerror(errno) ); 
                return; 
        } 


        return; 



int writing(int fd, const void *vptr, int n ) 

    int nwritten; 
    int nleft = n; 
    const char *ptr=(char*)vptr; 
    while(nleft > 0){ 
        if( (nwritten = write(fd,ptr,nleft)) <= 0){ 
            if( errno == EINTR ){ 
                nwritten =0; 
            }else{ 
                return -1; 
            } 
        } 
        nleft -= nwritten; 
        ptr += nwritten; 
    } 
    return n; 

/* read file */ 
static int read_file(char *filename, unsigned char *buffer, int maxlen) { 
    int fd,len; 


    if ( (fd = open(filename, O_RDONLY)) == -1) { 
        perror( filename ); 
        return -1; 
    } 
    len = read (fd, buffer, maxlen); 
    close(fd); 
    return len; 



/* 
 * 
 */ 
void * forwarding(void *argv){ 
    int conn_clientfd = ((int*)argv)[0]; 
    int conn_serverfd = ((int*)argv)[1]; 
    int maxfd = max( conn_clientfd, conn_serverfd ); 
    int i = 0; 
    fd_set fdread; 
    FD_ZERO(&fdread); 
    unsigned char buffer[MAXSIZE]={0}; 
    int nreceived = 0; 
    int nwritten = 0; 


    while(1) { 
        FD_SET(conn_clientfd, &fdread); 
        FD_SET(conn_serverfd, &fdread); //连接到rdp服务器端的socket 
        int ret=select( maxfd+1 ,&fdread,NULL,NULL,NULL); 
        if( ret < 0 ) BREAK_PERROR; 
         
        ret = FD_ISSET(conn_serverfd,&fdread); 
        if( ret < 0 ) BREAK_PERROR \ 
        else if( ret > 0 ){ //traffic from RDP client 
            nreceived = read(conn_serverfd,buffer,MAXSIZE); 
            if(nreceived < 0){ 
                if(errno == EINTR) CONTINUE_PERROR; 
                BREAK_PERROR; 
            } 
            if(nreceived == 0) break; 
             
            printf("#seq %d from client to server\n",packet_count++); 
            nwritten = writing( conn_clientfd, buffer, nreceived ); 
            if( nwritten < 0 || nwritten != nreceived ) BREAK_PERROR; 
        } 
         
        ret = FD_ISSET(conn_clientfd,&fdread); 
        if( ret < 0 ) BREAK_PERROR \ 
        else if( ret > 0 ){ 
            nreceived = read(conn_clientfd, buffer, MAXSIZE ); 
            if( nreceived < 0 ){ 
                if( errno == EINTR ) CONTINUE_PERROR; 
                BREAK_PERROR; 
            } else if( nreceived == 0 ){ 
                break; 
            } 
            printf("#seq %d from server to client\n",packet_count++); 
            int nwritten = writing( conn_serverfd, buffer, nreceived ); 
            if( nwritten < 0 || nwritten!=nreceived ) BREAK_PERROR; 
        } 
    } 
    close(conn_clientfd); 
    close(conn_serverfd); 
    exit(0); 



int Listen(const char *ip,const char *port){ 
    int listenfd = socket(AF_INET,SOCK_STREAM,0); 
    if( listenfd < 0 ){ 
        perror("Listen() Failed to create socket\n" ); 
        exit(errno); 
    } 
    struct sockaddr_in listenaddr; 
    bzero( &listenaddr, sizeof(listenaddr) ); 
    listenaddr.sin_family = AF_INET; 
    listenaddr.sin_port = htons( atoi( port ) ); 
    int ret = inet_pton( AF_INET, ip, &listenaddr.sin_addr ); 
    if( ret < 0 ) EXIT_PERROR; 
    int optval = 1; 
    ret = setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval) ); 
    if( ret < 0 ) EXIT_PERROR; 
    ret = bind( listenfd, (struct sockaddr*)&listenaddr, sizeof( listenaddr ) ); 
    if( ret < 0 ) EXIT_PERROR; 
    ret = listen( listenfd, 16 ); 
    if( ret < 0 ) EXIT_PERROR; 


    return listenfd; 



int Connect(const char *ip, const char *port) 

    int clientfd = socket(AF_INET,SOCK_STREAM,0); 
    if( clientfd < 0 ) RETURN_PERROR(-1); 
    struct sockaddr_in addr; 
    bzero(&addr, sizeof(addr) ); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons( atoi( port ) ); 
    int ret = inet_pton( AF_INET, ip, &addr.sin_addr ); 
    if( ret <= 0 ) RETURN_PERROR(-1); 
    ret = connect( clientfd, (struct sockaddr*)&addr, sizeof(addr) ); 
    if( ret < 0 ) RETURN_PERROR(-1); 
    return clientfd; 



int main(int argc,char* argv[]){ 
    int listenerfd,conn_serverfd,conn_clientfd; 
    struct sockaddr_in     localaddr; 
    struct sockaddr_in     clientaddr; 
      
    char localport[8]={0};//本地监听端口 
    char remoteip[20]={0};//远程ip 
    char remoteport[8]={0};//远程端口 


    int i=0; 


    /* config */ 
    FILE *fd; 
    if((fd = fopen("./conf","r"))== NULL) EXIT_PERROR; 
    fscanf(fd,"localport:%s\nremoteip:%s\nremoteport:%s\n", localport,remoteip,remoteport); 
     
    /* initialize */ 
    init_daemon(); 
    init_signal(); 
     
    /* listening */ 
    listenerfd = Listen( "localhost" , localport ); 
    while(1){ 
        conn_serverfd = accept(listenerfd,NULL,NULL); 
        if( conn_serverfd < 0 ) CONTINUE_PERROR; 
        conn_clientfd = Connect( remoteip, remoteport ); 
        if( conn_clientfd < 0 ){ 
            close( conn_serverfd ); 
            CONTINUE_PERROR; 
        } 
        printf( "serverfd:%d,clientfd:%d\n", conn_serverfd, conn_clientfd ); 
        set_keepalive( conn_clientfd ); 
        set_keepalive( conn_serverfd ); 
        if( fork() == 0 ){ 
            pthread_t tid1,tid2; 
            int conn_socks[2]; 
            conn_socks[0] = conn_clientfd; 
            conn_socks[1] = conn_serverfd; 
            pthread_create( &tid1, NULL, forwarding , conn_socks ); 
            pthread_join( tid1, NULL ); 
            exit(0); 
        } 
        close( conn_serverfd ); 
        close( conn_clientfd ); 
    } 
    close( listenerfd ); 
    return 0; 
原创粉丝点击