分享一段基于UDP的单线程网络点对点数据包收发测试程序。这段程序我是用来测试使用recvmmsg()与sendmmsg()后的丢包率(这两个函数的信息可以man出来),使用g++编译,程序中可能有不足的地方还望指出。
文件一:wrap.h
-
#ifndef _WRAP_H_
-
#define _WRAP_H
-
-
#ifndef __USE_GNU
-
#define __USE_GNU
-
#endif
-
-
#include <sys/socket.h>
-
#include <sys/types.h>
-
#include <string.h>
-
#include <stdio.h>
-
#include <errno.h>
-
#include <unistd.h>
-
#include <stdlib.h>
-
#include <netinet/in.h>
-
#include <arpa/inet.h>
-
-
#define DATNUM 100
-
-
#endif
文件二:server.c
-
/* server.c */
-
#include "wrap.h"
-
#define SERV_PORT 8000
-
-
int main(void)
-
{
-
struct sockaddr_in servaddr, clitaddr[DATNUM];
-
int sockfd, i, n;
-
char buf[DATNUM][3];
-
struct mmsghdr msgvec[DATNUM];
-
struct iovec dataiov[DATNUM];
-
struct timespec *timeout;
-
timeout = (struct timespec *)malloc(sizeof(struct timespec));
-
unsigned long b = 0, a = 0;
-
-
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
-
-
bzero(&servaddr, sizeof(servaddr));
-
bzero(clitaddr, sizeof(clitaddr));
-
bzero(msgvec, sizeof(msgvec));
-
bzero(dataiov, sizeof(dataiov));
-
-
servaddr.sin_family = AF_INET;
-
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
-
servaddr.sin_port = htons(SERV_PORT);
-
bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
-
timeout->tv_sec = 5;
-
timeout->tv_nsec = 0;
-
printf("Accepting connections ...\n");
-
-
while(1) {
-
for (i = 0; i < DATNUM; i++) { // 准备好待接收的包
-
dataiov[i].iov_base = buf[i];
-
dataiov[i].iov_len = 3;
-
msgvec[i].msg_hdr.msg_name = &clitaddr;
-
msgvec[i].msg_hdr.msg_namelen = 16;
-
msgvec[i].msg_hdr.msg_iov = &dataiov[i];
-
msgvec[i].msg_hdr.msg_iovlen = DATNUM;
-
}
-
n = recvmmsg(sockfd, msgvec, DATNUM, 0, timeout);
-
if (n == -1) {
-
b++;
-
printf("recv_err_num:%ld\n", b); // 出错包数量
-
}
-
else {
-
a++;
-
printf("recv_crt_num:%ld\n", a); // 正确接收
-
}
-
}
-
}
文件三:client.c
-
/* client.c */
-
#include "wrap.h"
-
#define SERV_PORT 8000
-
-
int main(int argc, char *argv[]) // 参数是要发送的数据包个数
-
{
-
-
struct sockaddr_in servaddr;
-
int sockfd, n, i, j, a;
-
char m[6] = "CHINA";
-
struct mmsghdr msgvec[DATNUM];
-
struct iovec dataiov[DATNUM];
-
-
if (argc != 2) {
-
printf("Please input a argument.\n");
-
exit(0);
-
}
-
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
-
if (sockfd < 0) {
-
printf("socket creating fail!\n");
-
return 0;
-
}
-
bzero(&servaddr, sizeof(struct sockaddr_in));
-
bzero(msgvec, sizeof(msgvec));
-
bzero(dataiov, sizeof(dataiov));
-
servaddr.sin_family = AF_INET;
-
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
-
servaddr.sin_port = htons(SERV_PORT);
-
-
for (i = 0, a = 0; i < atoi(argv[1]); i++) {
-
for(j = 0; j < DATNUM; j++) { // 构建数据包
-
bzero(&msgvec[j], sizeof(struct mmsghdr));
-
bzero(&dataiov[j], sizeof(struct iovec));
-
msgvec[j].msg_hdr.msg_name = &servaddr;
-
msgvec[j].msg_hdr.msg_namelen = 16;
-
dataiov[j].iov_base = &m;
-
dataiov[j].iov_len = 3;
-
msgvec[j].msg_hdr.msg_iov = &dataiov[j];
-
msgvec[j].msg_hdr.msg_iovlen = DATNUM;
-
}
-
-
n = sendmmsg(sockfd, msgvec, DATNUM, 0);
-
if (n == -1) {
-
printf("sendmmsg error\n");
-
exit(0);
-
}
-
else a++;
-
-
// usleep(1); // 测试时最好注释掉,会影响结果
-
}
-
printf("send_num = %d\n", a);
-
return 0;
-
}
阅读(1110) | 评论(0) | 转发(0) |