Chinaunix首页 | 论坛 | 博客
  • 博客访问: 73643
  • 博文数量: 21
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 189
  • 用 户 组: 普通用户
  • 注册时间: 2015-08-24 20:56
文章分类

全部博文(21)

文章存档

2016年(1)

2015年(20)

我的朋友

分类: 服务器与存储

2015-09-21 14:46:37

分享一段基于UDP的单线程网络点对点数据包收发测试程序。这段程序我是用来测试使用recvmmsg()与sendmmsg()后的丢包率(这两个函数的信息可以man出来),使用g++编译,程序中可能有不足的地方还望指出。

  文件一:wrap.h

点击(此处)折叠或打开

  1. #ifndef _WRAP_H_
  2. #define _WRAP_H

  3. #ifndef __USE_GNU
  4. #define __USE_GNU
  5. #endif

  6. #include <sys/socket.h>
  7. #include <sys/types.h>
  8. #include <string.h>
  9. #include <stdio.h>
  10. #include <errno.h>
  11. #include <unistd.h>
  12. #include <stdlib.h>
  13. #include <netinet/in.h>
  14. #include <arpa/inet.h>

  15. #define DATNUM 100

  16. #endif
文件二:server.c

点击(此处)折叠或打开

  1. /* server.c */
  2. #include "wrap.h"
  3. #define SERV_PORT 8000

  4. int main(void)
  5. {
  6.  struct sockaddr_in servaddr, clitaddr[DATNUM];
  7.  int sockfd, i, n;
  8.  char buf[DATNUM][3];
  9.  struct mmsghdr msgvec[DATNUM];
  10.  struct iovec dataiov[DATNUM];
  11.  struct timespec *timeout;
  12.  timeout = (struct timespec *)malloc(sizeof(struct timespec));
  13.  unsigned long b = 0, a = 0;
  14.  
  15.  sockfd = socket(AF_INET, SOCK_DGRAM, 0);

  16.  bzero(&servaddr, sizeof(servaddr));
  17.  bzero(clitaddr, sizeof(clitaddr));
  18.  bzero(msgvec, sizeof(msgvec));
  19.  bzero(dataiov, sizeof(dataiov));

  20.  servaddr.sin_family = AF_INET;
  21.  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  22.  servaddr.sin_port = htons(SERV_PORT);
  23.  bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
  24.  timeout->tv_sec = 5;
  25.  timeout->tv_nsec = 0;
  26.  printf("Accepting connections ...\n");

  27.  while(1) {
  28.      for (i = 0; i < DATNUM; i++) {                 // 准备好待接收的包
  29.             dataiov[i].iov_base = buf[i];
  30.             dataiov[i].iov_len = 3;
  31.             msgvec[i].msg_hdr.msg_name = &clitaddr;
  32.             msgvec[i].msg_hdr.msg_namelen = 16;
  33.             msgvec[i].msg_hdr.msg_iov = &dataiov[i];        
  34.             msgvec[i].msg_hdr.msg_iovlen = DATNUM;
  35.      }
  36.      n = recvmmsg(sockfd, msgvec, DATNUM, 0, timeout);
  37.      if (n == -1) {
  38.          b++;
  39.          printf("recv_err_num:%ld\n", b);          // 出错包数量
  40.      }
  41.     else {    
  42.          a++;
  43.          printf("recv_crt_num:%ld\n", a);          // 正确接收
  44.      }
  45.  }
  46. }
文件三:client.c

点击(此处)折叠或打开

  1. /* client.c */
  2. #include "wrap.h"
  3. #define SERV_PORT 8000

  4. int main(int argc, char *argv[])      // 参数是要发送的数据包个数
  5. {

  6.  struct sockaddr_in servaddr;
  7.  int sockfd, n, i, j, a;
  8.  char m[6] = "CHINA";
  9.  struct mmsghdr msgvec[DATNUM];
  10.  struct iovec dataiov[DATNUM];
  11.  
  12.  if (argc != 2) {
  13.     printf("Please input a argument.\n");
  14.     exit(0);
  15.  }
  16.  sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  17.  if (sockfd < 0) {
  18.         printf("socket creating fail!\n");
  19.         return 0;
  20.  }
  21.  bzero(&servaddr, sizeof(struct sockaddr_in));
  22.  bzero(msgvec, sizeof(msgvec));
  23.  bzero(dataiov, sizeof(dataiov));
  24.  servaddr.sin_family = AF_INET;
  25.  inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
  26.  servaddr.sin_port = htons(SERV_PORT);

  27.  for (i = 0, a = 0; i < atoi(argv[1]); i++) {
  28.         for(j = 0; j < DATNUM; j++) {                // 构建数据包
  29.              bzero(&msgvec[j], sizeof(struct mmsghdr));
  30.              bzero(&dataiov[j], sizeof(struct iovec));
  31.              msgvec[j].msg_hdr.msg_name = &servaddr;
  32.              msgvec[j].msg_hdr.msg_namelen = 16;
  33.              dataiov[j].iov_base = &m;
  34.              dataiov[j].iov_len = 3;
  35.              msgvec[j].msg_hdr.msg_iov = &dataiov[j];
  36.              msgvec[j].msg_hdr.msg_iovlen = DATNUM;
  37.         }
  38.      
  39.         n = sendmmsg(sockfd, msgvec, DATNUM, 0);
  40.          if (n == -1{
  41.              printf("sendmmsg error\n");
  42.             exit(0);
  43.         }
  44.         else  a++;

  45.         // usleep(1);     // 测试时最好注释掉,会影响结果
  46.  }
  47.  printf("send_num = %d\n", a);       
  48.  return 0;
  49. }


阅读(1116) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~