接上一篇(http://blog.chinaunix.net/uid-30430953-id-5201726.html),这段程序同样用来测试使用recvmmsg()与sendmmsg()后的丢包率,只不过这次用pthread_create()创建了4个线程,使用g++ client.c -o client -lpthread编译。由于第一次用pthread_create()函数,不是很熟悉,程序中有不足的地方还望指出。
文件一: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 <stdlib.h>
-
#include <pthread.h>
-
#include <unistd.h>
-
#include <netinet/in.h>
-
#include <arpa/inet.h>
-
#define DATNUM 100
-
-
#endif
文件二:server.c
-
/* server.c */
-
#include "wrap.h"
-
#define SERV_PORT 8000
-
#define NUM_THREADS 4 // 创建的线程数
-
-
unsigned long b = 0, a = 0;
-
-
void *recv_dat(void *args) // 线程处理函数
-
{
-
struct sockaddr_in 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));
-
-
bzero(clitaddr, sizeof(clitaddr));
-
bzero(msgvec, sizeof(msgvec));
-
bzero(dataiov, sizeof(dataiov));
-
-
timeout->tv_sec = 5;
-
timeout->tv_nsec = 0;
-
sockfd = (int)(*((int*)args));
-
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_num:%ld\n", a);
-
}
-
}
-
}
-
-
int main(void)
-
{
-
struct sockaddr_in servaddr;
-
int sockfd, rc, t;
-
pthread_t thread[NUM_THREADS];
-
-
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
-
bzero(&servaddr, sizeof(servaddr));
-
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));
-
printf("Accepting connections ...\n");
-
-
for (t = 0; t < NUM_THREADS; t++) {
-
printf("Creating thread %d\n", t);
-
rc = pthread_create(&thread[t], NULL, recv_dat, &sockfd);
-
if (rc) {
-
perror("Error");
-
return EXIT_FAILURE;
-
}
-
}
-
sleep(5); // 67~70行好像没什么用,因为程序来不到这里
-
for(t = 0; t < NUM_THREADS; t++)
-
pthread_join(thread[t], NULL);
-
return EXIT_SUCCESS;
-
}
文件三: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[8] = "FREEDOM";
-
struct mmsghdr msgvec[DATNUM];
-
struct iovec dataiov[DATNUM];
-
socklen_t servaddr_len;
-
-
if (argc != 2) {
-
printf("Usage: fileclient \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++) { // for循环里是将数据打包
-
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;
-
}
阅读(1796) | 评论(0) | 转发(0) |