UDP数据接收服务器

  • V8_916036
    了解作者
  • 2.9KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-04-12 18:43
    上传日期
这是我在做一个要用UDP方式进行数据传输时,自己写的一个多线程的UDP数据接收服务器, 它能将接收到的UDP数据包存成文件,并提供数据包接收时间监测; 还支持键盘命令响应,以将数据写到新的文件,和退出程序;
udp_server.rar
  • udp_server
  • compile_cmd
    68B
  • udp_server.c
    7.6KB
内容介绍
/* ****************************************************************************** * \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: \n"); printf("-p port : set listern port\n"); printf("-o file : set output filename\n"); printf("-h : print help infomation\n"); printf("eg :\n"); printf("$./udp_server -p 10001 -o test.dat\n"); 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\n"); } 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\n", 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\n"); bTerminalFlag = 1; break; } if (key == 'n') { verbose++; printf("verbose = %d\n", verbose); bTerminalFlag = 1; printf("Waiting for thread to finish...\n"); res = pthread_join(tid_sock, &thread_result); if (res != 0) { perror("Thread join failed"); exit(EXIT_FAILURE); } printf("Thread joined, it returned %s\n", (char*)thread_result); memset(filename_new, 0, sizeof(filename_new)); fflush(fp_udp); fclose(fp_udp); } if (key == '?') { printf("key function\n" "? show this help\n" "+ increase verbosity\n" "- decrease verbosity\n" "q quit\n" ); } } } /* end */ printf("Waiting for thread to finish...\n"); res = pthread_join(tid_sock, &thread_result); if (res != 0) { perror("Thread join failed"); exit(EXIT_FAILURE); } printf("Thread joined, it returned %s\n", (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\n", 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(SERVPORT); 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(1) 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\n", 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\n"); } int parse_params(int argc, char** argv, int* port, char* f) { int c, index; opterr = 0; while ((c = getopt_long(argc, argv, "p:o:h", opts, NULL)) != -1) { switch (c) { case 'p': *port = atoi(optarg); break; case 'o': strcpy(f, optarg); break; case 'h': default: printf("Usage: \n"); printf("-p port : set listern port\n"); printf("-o file : set output filename\n"); printf("-h : print help infomation\n"); printf("eg :\n"); printf("$./udp_server -p 10001 -o test.dat\n"); exit(1); } } printf("port : %d\nfile : %s\n",*port, f); for (index = optind; index < argc; index++) printf("Non-option argument %s\n", argv[index]); return 0; } /* For keyboard */ static void term_init(void) { if (!run_as_daemon) { struct termios tty; tcgetattr(0, &tty); oldtty = tty; atexit(term_exit); tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP |INLCR|IGNCR|ICRNL|IXON); tty.c_oflag |= OPOST; tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); tty.c_cflag &= ~(CSIZE|PARENB); tty.c_cflag |= CS8; tty.c_cc[VMIN] = 1; tty.c_cc[VTIME] = 0; tcsetattr (0, TCSANOW, &tty); /* Quit (POSIX). */ signal(SIGQUIT, sigterm_handler); } signal(SIGINT , sigterm_handler); signal(SIGTERM, sigterm_handler); } static void term_exit(void) { printf("%s\n", "TERMINATION"); if (!run_as_daemon) tcsetattr(0, TCSANOW, &oldtty); exit(1); } static void sigterm_handler(int sig) { received_sigterm = sig; q_pressed++; term_exit(); } /* * \Func * read_key * \Descript * read a key without blocking */ static int read_key(void) { int n = 1; unsigned char ch; struct timeval tv; fd_set rfds; if (run_as_daemon) return -1; FD_ZERO(&rfds); FD_SET(0, &rfds); tv.tv_sec = 0; tv.tv_usec = 0; n = select(1, &rfds, NULL, NULL, &tv); if (n > 0) { n = read(0, &ch, 1); if (n == 1) return ch; return n; } return -1; } /* end */
评论
    相关推荐