zoukankan      html  css  js  c++  java
  • UDP数据接收服务器

    简介
    这是我在做一个要用UDP方式进行数据传输时,自己写的一个多线程的UDP数据接收服务器,
    它能将接收到的UDP数据包存成文件,并提供数据包接收时间监测;
    还支持键盘命令响应,以将数据写到新的文件,和退出程序;
    闲言少述,直接上代码;


    代码:
    /*
     ******************************************************************************
     * File
     *   udp_server.c
     * Descript
     *   Receive udp datas and write into file, implement by multi-threads
     * Author
     *   Anderson Yan
     * Create
     *   2013-9-18
     ******************************************************************************
     */


    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <pthread.h>
    #include <sys/time.h>
    #include <unistd.h>


    #include <getopt.h>
    /* For signal response */
    #include <signal.h>
    #include <limits.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <sys/time.h>
    #include <termios.h>


    static struct termios oldtty;
    static int q_pressed = 0;
    static int verbose = 0;
    static int using_stdin = 0;
    static int run_as_daemon = 0;




    static volatile int received_sigterm = 0;


    static void term_init(void);
    static void term_exit(void);
    static void sigterm_handler(int sig);
    static int read_key(void);
    /* end */


    /* For parsing command-line parameters */
    extern char* optarg;
    extern int   opterr;
    struct option opts[] = 
    {
      {"port", required_argument, NULL, 'p'},
      {"out",  required_argument, NULL, 'o'},
      {"help", required_argument, NULL, 'h'},
      {0,0,0,0}
    };


    int parse_params(int agrc, char** argv, int* port, char* f);
    /* end */


    #define SERVPORT 10000
    #define MAXDATASIZE 2048
    FILE* fp_udp = NULL;
    void *sock_recv_udp(void *arg);


    static int bTerminalFlag = 0;


    int main(int argc, char** argv)
    {
      int file_number = 0;
      int  udp_port = SERVPORT;
      char filename[128] = "test.dat";
      char filename_new[256] = {0};


      int res;
      pthread_t tid_sock;
      void *thread_result;


      /* 命令行输入参数解析 */
      if (argc < 2)
      {
        printf("Usage: ");
        printf("-p port : set listern port ");
        printf("-o file : set output filename ");
        printf("-h      : print help infomation ");
        printf("eg : ");
        printf("$./udp_server -p 10001 -o test.dat "); 
        exit(1);
      }
      parse_params(argc, argv, &udp_port, filename); 


      /* SIGNAL,键盘命令响应的初始化 */
      int key;
      if (!using_stdin)
      {
        if (verbose >=0)
          printf("Press [q] to stop, [?] for help, [n] for creating new file ");
      }
      term_init();
      /* end */


      fp_udp = fopen(filename, "wb");
      if (fp_udp == NULL)
      {
        perror("Open file failed");
        exit(EXIT_FAILURE);
      }


      res = pthread_create(&tid_sock, NULL, sock_recv_udp, (void*)&udp_port);
      if (res != 0)
      {
        perror("Thread creation failed");
        exit(EXIT_FAILURE);
      }


      /* Response for keyboard */
      for(; received_sigterm == 0;)
      {
        if (verbose != file_number)
        {
          file_number = verbose;
          bTerminalFlag = 0;
          snprintf(filename_new, sizeof(filename_new),"%s.%d",filename, file_number);
          printf("Create new file : %s ", filename_new);


          fp_udp = fopen(filename_new, "wb");
          if (fp_udp == NULL)
          {
            perror("Open file failed");
            exit(EXIT_FAILURE);
          }


          res = pthread_create(&tid_sock, NULL, sock_recv_udp, (void*)&udp_port);
          if (res != 0)
          {
            perror("Thread creation failed");
            exit(EXIT_FAILURE);
          }
        }
        /* if 'q' pressed, exits */
        if (!using_stdin)
        {
          if (q_pressed)
            break;


          /* read_key() returns 0 on EOF */
          key = read_key();
          if (key == 'q')
          {
            printf("quit ");
            bTerminalFlag = 1;
            break;
          }
          if (key == 'n')
          {
            verbose++;
            printf("verbose = %d ", verbose);


            bTerminalFlag = 1;
            printf("Waiting for thread to finish... ");
            res = pthread_join(tid_sock, &thread_result);
            if (res != 0)
            {
              perror("Thread join failed");
              exit(EXIT_FAILURE);
            }
            printf("Thread joined, it returned %s ", (char*)thread_result);


            memset(filename_new, 0, sizeof(filename_new));
            fflush(fp_udp);
            fclose(fp_udp);
          }
          if (key == '?')
          {
            printf("key function "
                   "? show this help "
                   "n create new file "
                   "q quit ");
          }
        }
      }
      /* end */


      printf("Waiting for thread to finish... ");
      res = pthread_join(tid_sock, &thread_result);
      if (res != 0)
      {
        perror("Thread join failed");
        exit(EXIT_FAILURE);
      }
      printf("Thread joined, it returned %s ", (char*)thread_result);


      fflush(fp_udp);
      fclose(fp_udp);


      return 0;
    }




    void *sock_recv_udp(void *arg)
    {
      int port = *(int*)arg;


      int sockfd, recvbytes;
      char rcv_buf[MAXDATASIZE], snd_buf[MAXDATASIZE];
      struct sockaddr_in server_addr;
      socklen_t addr_size=sizeof(server_addr);
      int pkt_cnt = 0;


      struct timeval start_time, end_time;
      double time_used;


      int optval;
      printf("PORT : %d ", port);


      if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
      {
        perror("socket:");
        exit(1);
      }


      server_addr.sin_family = AF_INET;
      server_addr.sin_port = htons(port);
      server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
      memset(&(server_addr.sin_zero), 0, 8);


      if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))==-1)
      {
        perror("bind:");
        exit(1);
      }


      optval = 1;
      int ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));


      while(!bTerminalFlag)
      {
        addr_size = sizeof(struct sockaddr);
        gettimeofday(&start_time, 0);


        /* receive the data from "server_addr" by "sockfd" and store into "rcv_buf" */
        if ((recvbytes = recvfrom(sockfd, rcv_buf, MAXDATASIZE, 0,
    (struct sockaddr*)&server_addr, &addr_size)) == -1)
        {
          perror("recv:");
          exit(1);
        }


        fwrite(rcv_buf, 1, recvbytes, fp_udp);
        fflush(fp_udp);


        gettimeofday(&end_time, 0);
        time_used = 1000000 * (end_time.tv_sec - start_time.tv_sec)
                    + end_time.tv_usec - start_time.tv_usec;
        time_used /= 1000;
        printf("recv:%s:%d : pkt_cnt = %6d :  %4d bytes : time(ms) = %f ", 
      inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port), 
      pkt_cnt, recvbytes, time_used);


        pkt_cnt++;
      }
      close(sockfd);


      pthread_exit("thread sock_recv_udp over ");
    }


    完整的代码可以在这里下载:
    http://download.csdn.net/detail/fireroll/6286649

     
  • 相关阅读:
    动态规划——Best Time to Buy and Sell Stock IV
    动态规划——Split Array Largest Sum
    动态规划——Burst Ballons
    动态规划——Best Time to Buy and Sell Stock III
    动态规划——Edit Distance
    动态规划——Longest Valid Parentheses
    动态规划——Valid Permutations for DI Sequence
    构建之法阅读笔记05
    构建之法阅读笔记04
    构建之法阅读笔记03
  • 原文地址:https://www.cnblogs.com/james1207/p/3329150.html
Copyright © 2011-2022 走看看