Linux下利用epoll实现两台机器之间的UDP传输丢包统计
来源:互联网 发布:javascript脚本和图片 编辑:程序博客网 时间:2024/06/05 18:42
公司机房到阿里云的数据传输有时候会出现丢包,所以需要程序来进行查询和排查,公司前辈写了一个程序来进行机器之间的丢包统计。
服务器:pong.cpp
#include <sys/types.h>#include <sys/socket.h>#include <string.h>#include <netinet/in.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#define MAXLINE 1500#define SERV_PORT 2019 //服务器端口号void do_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen){ int n, jzq_num = 0; socklen_t len; char mesg[MAXLINE]; int i ; for(;;) { len = clilen; /* waiting for receive data */ n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len); mesg[n]=0; printf("recvfrom data:%d %d\n",n, ++jzq_num); printf("%s\n",mesg); /* sent data back to client */ sendto(sockfd, mesg, n, 0, pcliaddr, len); }}int main(int argc,char *argv[]){ int sockfd; int m_port = SERV_PORT; int result, buf_len; int len = sizeof (buf_len); struct sockaddr_in servaddr, cliaddr; if (argc >=2) sscanf(argv[1],"%d",&m_port); sockfd = socket(AF_INET, SOCK_DGRAM, 0); /* create a socket */ /* init servaddr */ bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(m_port); printf("port:%d\n", m_port); result = getsockopt((unsigned int)sockfd, SOL_SOCKET, SO_RCVBUF, (char *)&buf_len, (socklen_t *)&len); printf ("one:getsock_recvbuf-> result:%s buf_len:%d\n", result?"NO":"YES", buf_len); if(result == 0 && buf_len < 1024*1024) { buf_len = 1024*1024; setsockopt((unsigned int)sockfd, SOL_SOCKET, SO_RCVBUF, (char *)&buf_len, len); //接收缓冲区大小为1MB printf ("setsock_recvbuf-> result:%s buf_len:%d\n", result?"NO":"YES", buf_len); result = getsockopt((unsigned int)sockfd, SOL_SOCKET, SO_RCVBUF, (char *)&buf_len, (socklen_t *)&len); printf ("two:getsock_recvbuf-> result:%s buf_len:%d\n", result?"NO":"YES", buf_len); } /* bind address and port to socket */ if(bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { perror("bind error"); exit(1); } printf("UPD servese is bind success and do_echo now\n"); do_echo(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr)); return 0;}
测试程序check.cpp
#include <netinet/in.h>#include <sys/socket.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/epoll.h>#include <time.h>#include <unistd.h>#include <sys/types.h>#include <arpa/inet.h>#include <sys/time.h>#define MAXSIZE 1024#define FDSIZE 1024#define EPOLLEVENTS 20#define SERV_PORT (9999)//你需要连接的服务器端口号#define LOCAL_PORT (0) //UDP传输端口,0表示系统分配#define WAIT_TIME (100)static int handle_connection(int sockfd, struct sockaddr_in *servaddr, int flag);static int handle_events(int epollfd,struct epoll_event *events,int num,int sockfd,char *buf, struct sockaddr_in *servaddr);static int do_read(int epollfd,int fd,int sockfd,char *buf, struct sockaddr_in *servaddr);static void add_event(int epollfd,int fd,int state);static void delete_event(int epollfd,int fd,int state);static void modify_event(int epollfd,int fd,int state);char send_buf[MAXSIZE];char ip[50];int check(char *ip, int port, int flag){ int sockfd; struct sockaddr_in servaddr; struct sockaddr_in clientaddr; int res ; sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(port); servaddr.sin_addr.s_addr = inet_addr(ip); bzero(&clientaddr, sizeof(clientaddr)); clientaddr.sin_family = AF_INET; clientaddr.sin_port = htons(LOCAL_PORT); clientaddr.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(sockfd, (struct sockaddr *)&clientaddr, sizeof(clientaddr)) == -1) { perror("bind error"); exit(1); } sockaddr_in addrMy; memset(&addrMy,0,sizeof(addrMy)); int leng = sizeof(addrMy); if (getsockname(sockfd, (sockaddr*)&addrMy, (socklen_t*)&leng) != 0) { puts("Getsockname Error!"); return 0; } printf("Current Socket PORT->%d ",ntohs(addrMy.sin_port)); fflush(stdout); res = handle_connection(sockfd, &servaddr, flag); close(sockfd); return res;}void print_cur_time(){ time_t timep; struct tm *p; time(&timep); p = localtime(&timep); //取得当地时间 printf ("%d-%02d-%02d %02d:%02d:%02d ",(1900+p->tm_year), (1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); fflush(stdout);}int main(int argc,char *argv[]){ FILE *fp; int num = 0, lost_num = 0; while(1) { fp = fopen("./home/jzq/Check/poxy.txt*/", "r");//自己创目录文件,poxy.txt里是要连的ip地址 if(fp == NULL) { printf("The poxy.txt not exit\n"); return 0; } while(~fscanf(fp, "%s", ip)) { print_cur_time(); printf("ALY -> %s ", ip); fflush(stdout); check(ip, SERV_PORT, 2); sleep(0.1); } fclose(fp); } return 0;}static int handle_connection(int sockfd, struct sockaddr_in *servaddr, int flag){ int epollfd; struct epoll_event events[EPOLLEVENTS]; int ret, len, num = 30; int lost_num =0; epollfd = epoll_create(FDSIZE); add_event(epollfd,sockfd,EPOLLIN); while(num--) { len = 20; //包长,可以按需要增大,但要注意传输时间要相应增大 memset(send_buf, '6', len); send_buf[len] = 0; if(sendto(sockfd, send_buf, len, 0, (struct sockaddr*)servaddr, sizeof(struct sockaddr_in)) <= 0) { printf("sendto error"); continue; } ret = epoll_wait(epollfd, events, epollevents, wait_time); if(ret > 0 && (len = handle_events(epollfd, events, ret, sockfd, send_buf, servaddr)) > 0) { if(!len) printf("unkonw\n"); } else { lost_num++; printf("."); fflush(stdout); } } close(epollfd); printf("lost:%d%\n", lost_num*100/30); return lost_num;}static int handle_events(int epollfd,struct epoll_event *events,int num,int sockfd,char *buf, struct sockaddr_in *servaddr){ int fd; int i; for (i = 0;i < num;i++) { fd = events[i].data.fd; if ((events[i].events & EPOLLIN) && (fd == sockfd)) return do_read(epollfd,fd,sockfd,buf, servaddr); } return -1;}static int do_read(int epollfd,int fd,int sockfd,char *buf, struct sockaddr_in *servaddr){ socklen_t len = sizeof(struct sockaddr_in); return recvfrom(sockfd, buf, MAXSIZE, MSG_DONTWAIT, (struct sockaddr *)servaddr, &len);}static void add_event(int epollfd,int fd,int state){ struct epoll_event ev; ev.events = state; ev.data.fd = fd; epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&ev);}static void delete_event(int epollfd,int fd,int state){ struct epoll_event ev; ev.events = state; ev.data.fd = fd; epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,&ev);}static void modify_event(int epollfd,int fd,int state){ struct epoll_event ev; ev.events = state; ev.data.fd = fd; epoll_ctl(epollfd,EPOLL_CTL_MOD,fd,&ev);}
阅读全文
0 0
- Linux下利用epoll实现两台机器之间的UDP传输丢包统计
- Linux利用socket实现两台pc之间的数据传输功能,包括windows到linux,UDP实现
- Linux下查看两台机器之间速度
- linux scp-两台服务器之间传输数据的命令
- 两台linux之间传输文件的方法
- 两台linux服务器之间传输文件
- 两台Linux系统之间传输文件
- 两台Linux之间传输文件
- 两台Linux系统之间传输文件
- ssh实现两台机器之间穿越
- 利用网线在两台电脑之间传输文件
- Linux利用socket实现两台pc之间的数据传输功能,包括windows到linux,TCP/IP实现
- 如何在两台linux之间传输文件?
- 在两台linux系统之间传输文件夹
- 在两台Linux设备之间传输文件
- 两台Linux系统之间传输文件 secure CRT scp
- 两台Linux机器实现文件交换
- 两台Linux系统之间传输文件的几种方法
- teamviewer 安装成功
- 对CNN感受野一些理解
- fastjson简单运用
- Intellij IDEA Cannot resolve symbol XXX 问题解决办法汇总
- springMVC以及springBoot中的定时任务
- Linux下利用epoll实现两台机器之间的UDP传输丢包统计
- windows截图保存为文件
- Eclipse 3.5.2 maven插件安装
- mysql 常用数据库命令 (linux 下特殊操作)
- nginx访问量统计
- leetcode67-Add Binary
- STM32F407 Flash操作笔记
- 1024科学计数法 自己写加看答案
- 数据库面试常见问题