udp文件服务器,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

#include

#include

#include

#include

#include

#include

#include

#include

/* For signal response */

#include

#include

#include

#include

#include

#include

#include

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"

"n create new file\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(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\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");

}

完整的代码可以在这里下载:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值