📄 pathrate_rcv.c
字号:
/* This file is part of pathrate. pathrate is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. pathrate is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with pathrate; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*//*------------------------------------------------- pathrate : an end-to-end capcity estimation tool Author : Constantinos Dovrolis (dovrolis@cc.gatech.edu ) Ravi S Prasad ( ravi@cc.gatech.edu ) Release : Ver 2.4.1 Support : This work was supported by the SciDAC program of the US department --------------------------------------------------*/#define LOCAL#include "pathrate.h"#include "pathrate_rcv.h"int main(int argc, char* argv[]){ extern char *optarg; struct hostent *host_snd; struct sockaddr_in snd_tcp_addr, rcv_udp_addr; int opt_len, rcv_buff_sz, abort_phase1=0, outlier_lim, pack_incr_step, tmp, mss; int errflg=0; int file=0; int append=0; int gothostname=0; int quick_term=0; int i, j, c, sum_rtt, ctr_code, round, train_len, prev_train_len=2, train_len_P1, max_train_len, no_pack_sizes=40, no_trains, no_trains_P1, no_trains_per_size, trains_msrd=0, trains_rcvd=0, train_no, trains_per_size=0, no_modes_P1=0, no_modes_P2=0, cap_mode_ind=0, bad_tstamps=0, train_spacing, min_train_spacing, max_train_spacing, max_pack_sz, min_pack_sz_P1, pack_sz; short enough_data, path_overflow, adr_narrow, bad_train, bad_trains, measurs_vld_P1[NO_TRAINS_P1], measurs_vld_P2[NO_TRAINS_P2]; char filename[75], random_data[MAX_PACK_SZ], pack_buf[MAX_PACK_SZ]; struct timeval current_time, first_time, *time_stmps=NULL; double bw_msr, bin_wd, bw_range, avg_bw, rtt, adr, std_dev, delta, min_possible_delta, min_OSdelta[500], ord_min_OSdelta[500], mode_value, merit, max_merit, measurs_P1[NO_TRAINS_P1], measurs_P2[NO_TRAINS_P2], ord_measurs_P1[NO_TRAINS_P1], ord_measurs_P2[NO_TRAINS_P2]; mode_struct curr_mode, modes_P1[MAX_NO_MODES], modes_P2[MAX_NO_MODES]; time_t localtm; /* Print histogram of bandwidth measurements */ /* Check command line arguments */ verbose = 1; netlog = 0; append = 0; while ((c = getopt(argc, argv, "s:N:vQhHqo:O:")) != EOF){ switch (c) { case 's': gothostname = 1; strcpy(hostname,optarg); break; case 'Q': quick_term = 1; break; case 'q': Verbose=0; verbose=0; break; case 'v': Verbose=1; break; case 'o': file=1; strcpy(filename,optarg); break; case 'O': file=1; append=1; strcpy(filename,optarg); break; case 'N': netlog=1; strcpy(filename,optarg); break; case 'H': help() ; errflg++; break ; case 'h': help() ; errflg++; break ; case '?': errflg++; } } if (file){ if (append){ pathrate_fp = fopen(filename,"a"); fprintf(pathrate_fp, "\n\n"); } else{ pathrate_fp = fopen(filename,"w"); fprintf(pathrate_fp, "\n\n"); } } else{ pathrate_fp = fopen("pathrate.output" , "a" ) ; fprintf(pathrate_fp, "\n\n"); } if (netlog) { netlog_fp = fopen(filename,"a"); } if (errflg || !gothostname) { if (!gothostname) fprintf(stderr,"Need to specify sender's hostname!\n"); (void)fprintf(stderr, "usage: pathrate_rcv [-H|-h] [-Q] [-q|-v] [-o|-O <filename>]\ [-N <filename>] -s <sender>\n"); exit (-1); } if ((host_snd = gethostbyname(hostname)) == 0) { /* check if the user gave ipaddr */ if ( ( snd_tcp_addr.sin_addr.s_addr = inet_addr(hostname) ) == -1 ) { fprintf(stderr,"%s: unknown host\n", hostname); exit(-1); } else host_snd = gethostbyaddr(hostname,256,AF_INET); } /* Print arguments in the log file */ for (i=0; i<argc; i++) fprintf(pathrate_fp, "%s ", argv[i]); fprintf(pathrate_fp, "\n"); /* Print date and path info at trace file */ localtm = time(NULL); gethostname(pack_buf, 256); sprintf(message,"\tpathrate run from %s to %s on %s", hostname, pack_buf, ctime(&localtm)); prntmsg(pathrate_fp); if(verbose) prntmsg(stdout); /* Create data stream: UDP socket */ if ((sock_udp = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket(AF_INET,SOCK_DGRAM):"); exit(-1); } bzero((char*)&rcv_udp_addr, sizeof(rcv_udp_addr)); rcv_udp_addr.sin_family = AF_INET; rcv_udp_addr.sin_addr.s_addr = htonl(INADDR_ANY); rcv_udp_addr.sin_port = htons(UDPRCV_PORT); if (bind(sock_udp, (struct sockaddr*)&rcv_udp_addr, sizeof(rcv_udp_addr)) < 0) { perror("bind(sock_udp):"); exit(-1); } rcv_buff_sz = UDP_BUFFER_SZ; if (setsockopt(sock_udp,SOL_SOCKET,SO_RCVBUF,(char*)&rcv_buff_sz,sizeof(rcv_buff_sz))<0){ perror("setsockopt(sock_udp,SOL_SOCKET,SO_RCVBUF):"); exit(-1); } /* Create control stream: TCP connection */ if ((sock_tcp = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket(AF_INET, SOCK_STREAM):"); exit(-1); } opt_len = 1; if (setsockopt(sock_tcp, SOL_SOCKET, SO_REUSEADDR, (char*)&opt_len, sizeof(opt_len)) < 0) { perror("setsockopt(sock_tcp,SOL_SOCKET,SO_REUSEADDR):"); exit(-1); } bzero((char*)&snd_tcp_addr, sizeof(snd_tcp_addr)); snd_tcp_addr.sin_family = AF_INET; memcpy((void*)&(snd_tcp_addr.sin_addr.s_addr), host_snd->h_addr, host_snd->h_length); snd_tcp_addr.sin_port = htons(TCPSND_PORT); if (connect(sock_tcp,(struct sockaddr*)&snd_tcp_addr,sizeof(snd_tcp_addr))<0) { perror("Make sure that pathrate_snd runs at sender:"); exit(-1); } /* Estimate round-trip time */ sum_rtt=0; ctr_code=0; for(i=0; i<10; i++) { char mybuff[1024]; gettimeofday(&first_time, (struct timezone*)0); send_ctr_msg(ctr_code); recv_ctr_msg(sock_tcp, mybuff); gettimeofday(¤t_time, (struct timezone*)0); if (i>0) sum_rtt += time_to_us_delta(first_time, current_time);/* ignore first rtt */ } rtt = (double) (sum_rtt/9000.); sprintf(message,"\t--> Average round-trip time: %.1fms\n\n", rtt); prntmsg(pathrate_fp); if (verbose) prntmsg(stdout); /* Determine minimum train spacing based on rtt */ min_train_spacing = MIN_TRAIN_SPACING/1000; /* make msec */ if (min_train_spacing < rtt*1.25) { /* if the rtt is not much smaller than the specified train spacing, * increase minimum train spacing based on rtt */ min_train_spacing = rtt*1.25; } max_train_spacing = 2 * min_train_spacing; train_spacing = min_train_spacing; ctr_code = TRAIN_SPACING | (train_spacing<<8); send_ctr_msg(ctr_code); /* Send maximum packet size to sender (based on TCP MSS) */ opt_len = sizeof(mss); if (getsockopt(sock_tcp, IPPROTO_TCP, TCP_MAXSEG, (char*)&mss, &opt_len)<0){ perror("getsockopt(sock_tcp,IPPROTO_TCP,TCP_MAXSEG):"); exit(-1); } max_pack_sz = mss; if (max_pack_sz == 0) max_pack_sz = 1472; /* Make it Ethernet sized MTU */ else { max_pack_sz = mss+12; if (max_pack_sz > MAX_PACK_SZ) max_pack_sz = MAX_PACK_SZ; } ctr_code = MAX_PCK_LEN | (max_pack_sz<<8); send_ctr_msg(ctr_code); /* Also set the minimum packet size for Phase I */ min_pack_sz_P1 = MIN_PACK_SZ_P1; if (min_pack_sz_P1>max_pack_sz) min_pack_sz_P1=max_pack_sz; /* Measure minimum latency for kernel-to-user transfer of packet. */ srandom(getpid()); /* Create random payload; does it matter? */ for (i=0; i<MAX_PACK_SZ-1; i++) random_data[i]=(char)(random()&0x000000ff); bzero((char*)&pack_buf, MAX_PACK_SZ); memcpy(pack_buf+2*sizeof(long), random_data, (MAX_PACK_SZ-1)-2*sizeof(sizeof(long))); for (j=0; j<no_pack_sizes; j++) { pack_sz = max_pack_sz; for (i=0; i<10; i++) { sendto(sock_udp, pack_buf, pack_sz, 0, (struct sockaddr*)&rcv_udp_addr, sizeof(rcv_udp_addr)); gettimeofday(&first_time, (struct timezone*)0); recvfrom(sock_udp, pack_buf, pack_sz, 0, (struct sockaddr*)0, (int*)0); gettimeofday(¤t_time, (struct timezone*)0); delta = time_to_us_delta(first_time, current_time); min_OSdelta[j*10+i] = delta; } } /* Use median of measured latencies to avoid outliers */ order(min_OSdelta, ord_min_OSdelta, no_pack_sizes*10); min_possible_delta = ord_min_OSdelta[(int) (no_pack_sizes*10)/2];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -