tcp_server that is used to dump tcp datas

tcp_server that is used to dump tcp datas

#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/ in.h>
#include < string.h>
#include <getopt.h>

void get_remote_ip_and_port( struct sockaddr_in* s_add,  int* ip,  int* port) {
     if (!s_add || !ip || !port)  return;
    *port = ntohs(s_add->sin_port);
    *ip = s_add->sin_addr.s_addr;
}

void get_local_ip_and_port( int fd,  int* ip,  int* port) {
     if (fd <= 0 || !ip || !port)  return;
     struct sockaddr_in s_add;
     int sin_size =  sizeof(s_add);
     if(getsockname(fd, ( struct sockaddr *)&s_add, &sin_size) == 0 && s_add.sin_family == AF_INET && sin_size ==  sizeof(s_add)) {
        *port = ntohs(s_add.sin_port);
        *ip = s_add.sin_addr.s_addr;
    }
}

char* get_ip_str( int ip,  char* buf) {
    inet_ntop(AF_INET, &ip, buf, INET_ADDRSTRLEN);
     return buf;
}

void usage( char* argv0) {
    fprintf(stdout,
"Usage: %s [-p <port>] [-o output_file] [-h]\n\n"
" -p <port>        local port used to listen, by default, 8888\n"
" -o <output_file> output file used to record the data received from client, by default, dump to ./x.in\n"
" -h               print this usage\n"
"\n", argv0);
}

int main( int argc,  char* argv[]) {
     int sfp = 0;
     int nfp = 0;
     struct sockaddr_in s_add, c_add;
     int sin_size = 0;
     int server_port = 8888;
     int remote_port = 0;
     int remote_ip = 0;
     char remote_ip_str[INET_ADDRSTRLEN];
     int local_port = 0;
     int local_ip = 0;
     char local_ip_str[INET_ADDRSTRLEN];
     char output_file[256];
    sprintf(output_file, "%s", "./x.in");
    FILE* ofp = 0;

     char c = '\0';
     struct option long_options[] = {
        {"help", 0, 0, 'h'},
        {0,      0, 0, 0}
    };
     while (-1 != (c = getopt_long(argc, argv, ":p:o:h", long_options, NULL))) {
         switch (c) {
         case 'p':
            server_port = atoi(optarg);
             break;
         case 'o':
            sprintf(output_file, "%s", optarg);
             break;
         case 'h':
         case '?':  // an option character that was not in optstring
         case ':':  // an option with a missing argument
         default:
            usage(argv[0]);
             return -1;
        }
    }

    sfp = socket(AF_INET, SOCK_STREAM, 0);
     if (-1 == sfp) {
        printf("socket fail ! \n");
         return -1;
    }
    printf("socket ok !\n");

    bzero(&s_add,  sizeof( struct sockaddr_in));
    s_add.sin_family = AF_INET;
    s_add.sin_addr.s_addr = htonl(INADDR_ANY);
    s_add.sin_port = htons(server_port);

     if (-1 == bind(sfp, ( struct sockaddr *) (&s_add),  sizeof( struct sockaddr))) {
        printf("bind fail !\n");
         return -1;
    }
    printf("bind to %d ok!\n", server_port);

     if (-1 == listen(sfp, 5)) {
        printf("listen fail !\n");
         return -1;
    }
    printf("listen ok\n\n");

    ofp = fopen(output_file, "wrb");
     while (1) {
        sin_size =  sizeof( struct sockaddr_in);

        nfp = accept(sfp, ( struct sockaddr *) (&c_add), &sin_size);
         if (-1 == nfp) {
            printf("accept fail !\n");
             return -1;
        }
        printf("accept ok!\n");

        get_remote_ip_and_port(&c_add, &remote_ip, &remote_port);
        get_local_ip_and_port(nfp, &local_ip, &local_port);
        printf("establish connect %s:%d -> %s:%d\n", get_ip_str(remote_ip, remote_ip_str), remote_port, get_ip_str(local_ip, local_ip_str), local_port);

        fprintf(ofp, "----------------- establish connect %s:%d -> %s:%d -----------------{\n", get_ip_str(remote_ip, remote_ip_str), remote_port, get_ip_str(local_ip, local_ip_str), local_port);
         char buffer[1024];
         int recbytes = 0;
         int total_bytes = 0;
         while ((recbytes = read(nfp, buffer, 1024)) > 0) {
            total_bytes += recbytes;
            fwrite(buffer, 1, recbytes, ofp);
        }
        fprintf(ofp, "\n}---------------- receive %d bytes ------------------\n\n", total_bytes);

        printf("receive over!\n\n");
        fflush(stdout);
        fflush(ofp);
        close(nfp);
    }

    fclose(ofp);
    close(sfp);

     return 0;
}

你可能感兴趣的:(tcp_server that is used to dump tcp datas)