so true

          心懷未來,開創未來!
          隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0
          數據加載中……

          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;
          }

          posted on 2015-12-10 21:15 so true 閱讀(303) 評論(0)  編輯  收藏 所屬分類: C&C++Linux

          主站蜘蛛池模板: 新宾| 邵武市| 崇州市| 马边| 长岭县| 泾阳县| 泰宁县| 商水县| 巴彦淖尔市| 嘉义市| 黑河市| 南靖县| 寻乌县| 周宁县| 荥经县| 姚安县| 长寿区| 凭祥市| 年辖:市辖区| 东城区| 麟游县| 刚察县| 荆门市| 五常市| 奉节县| 卓资县| 麻江县| 康保县| 岐山县| 如皋市| 昂仁县| 榆树市| 屏东市| 新蔡县| 石屏县| 吉木萨尔县| 保康县| 年辖:市辖区| 南皮县| 随州市| 罗山县|