⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pathload_rcv.c

📁 pashload是应用在linux下的网络带宽测试源程序精确度比较高 ///////////////////////////////////// Pathload is a tool for es
💻 C
字号:
/* This file is part of pathload. pathload 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. pathload 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 pathload; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//*-------------------------------------------------   pathload : an end-to-end available bandwidth             estimation tool   Author   : Manish Jain ( jain@cc.gatech.edu )              Constantinos Dovrolis (dovrolis@cc.gatech.edu )   Release  : Ver 1.3.2   Support  : This work was supported by the SciDAC            program of the US department --------------------------------------------------*//* * $Header: /net/cvs/bwtest/pathload/pathload_rcv.c,v 1.139 2006/05/19 22:30:13 jain Exp $ */#define LOCAL#include "pathload_gbls.h"#include "pathload_rcv.h"int main(l_int32 argc, char *argv[]){  extern char *optarg;  struct hostent *host_snd;  struct sockaddr_in snd_tcp_addr, rcv_udp_addr;  struct utsname uts ;  l_int32 ctr_code;  l_int32 trend, prev_trend = 0;  l_int32 opt_len, rcv_buff_sz, mss;  l_int32 ret_val ;   l_int32 errflg=0;  l_int32 file=0;  char netlogfile[50],filename[50];  char ctr_buff[8], myname[50], buff[26];  char mode[4];  l_int32 c ;  struct itimerval expireat ;  struct sigaction sigstruct ;  slow=0;  requested_delay = 0;  interrupt_coalescence=0;  bad_fleet_cs=0;  num_stream = NUM_STREAM;  stream_len = STREAM_LEN ;  exp_flag = 1;  num=0;  snd_time_interval=0;   converged_gmx_rmx = 0 ;  converged_gmn_rmn = 0 ;  converged_rmn_rmx = 0 ;  counter = 0 ;  prev_actual_rate = 0;  prev_req_rate = 0 ;   cur_actual_rate = 0 ;  cur_req_rate = 0 ;  gettimeofday(&exp_start_time, NULL);  verbose=1;  bw_resol=0;  netlog=0;  increase_stream_len=0;  lower_bound=0;  if ( argc == 1 ) errflg++ ;  while ((c = getopt(argc, argv, "t:s:hw:vHqo:O:N:V")) != EOF)    switch (c)     {      case 't':        requested_delay = atoi(optarg);        break;      case 's':        strcpy(hostname,optarg);        break;      case 'w':        bw_resol = atof(optarg);        break;      case 'q':        Verbose=0;        verbose=0;        break;      case 'v':        Verbose=1;        break;      case 'O':        file=1;        strcpy(filename,optarg);        strcpy(mode,"a");        break;      case 'o':        file=1;        strcpy(filename,optarg);        strcpy(mode,"w");        break;      case 'H':      case 'h':        help() ;        break ;      case 'N':        netlog=1;         strcpy(netlogfile,optarg);        break;      case 'V':        VVerbose = 1;        break ;      case '?':        errflg++;        break ;    }  if (errflg)  {    fprintf(stderr, "usage: pathload_rcv [-q|-v] [-o <filename>] [-N <filename>]\[-w <bw_resol>] [-h|-H] -s <sender>\n");    exit (0);  }  if (netlog)    netlog_fp = fopen(netlogfile,"a");  if (file)    pathload_fp = fopen(filename,mode);  else    pathload_fp = fopen("pathload.log" , "a" ) ;  fprintf(pathload_fp, "\n\n");  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);    }  }  strncpy(buff, ctime(&(exp_start_time.tv_sec)), 24);  buff[24] = '\0';  bzero(myname,50);  if ( gethostname(myname ,50 ) == -1 )  {    if ( uname(&uts) < 0 )      strcpy(myname , "UNKNOWN") ;    else      strcpy(myname , uts.nodename) ;  }  if (verbose || Verbose)    printf("\n\nReceiver %s starts measurements at sender %s on %s \n", myname , hostname, buff);  fprintf(pathload_fp,"\n\nReceiver %s starts measurements at sender %s on %s \n", myname , hostname, buff);  if ((sock_udp = socket(AF_INET, SOCK_DGRAM, 0)) < 0)  {    perror("ERROR :: failed to open DGRAM socket:");    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 = 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("ERROR :: failed to bind DGRAM socket:");    exit(-1);  }  rcv_buff_sz = UDP_BUFFER_SZ;  if (setsockopt(sock_udp, SOL_SOCKET, SO_RCVBUF, &rcv_buff_sz, sizeof(rcv_buff_sz)) < 0)  {    rcv_buff_sz/=2;    if (setsockopt(sock_udp, SOL_SOCKET, SO_RCVBUF, &rcv_buff_sz, sizeof(rcv_buff_sz)) < 0)    {      printf("ERROR :: Unable to set socket buffer to %d .\n",rcv_buff_sz);      exit(-1);    }  }  opt_len = 1;  if (setsockopt(sock_udp, SOL_SOCKET, SO_REUSEADDR, &opt_len, sizeof(opt_len)) < 0)  {    perror("setsockopt(sock_udp,SOL_SOCKET,SO_REUSEADDR):");    exit(-1);  }  /* set up control channel */  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, &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 pathload_snd runs at sender:");    exit(-1);  }  if (fcntl(sock_tcp, F_SETFL, O_NONBLOCK) < 0)  {    perror("fcntl:");    exit(-1);  }  /*    measure max_pkt_sz (based on TCP MSS).    this is not accurate because it does not take into    account MTU of intermediate routers.  */  opt_len = sizeof(mss);  if (getsockopt(sock_tcp, IPPROTO_TCP, TCP_MAXSEG, (char*)&mss,(socklen_t *) &opt_len)<0)  {     perror("getsockopt(sock_tcp,IPPROTO_TCP,TCP_MAXSEG):");     exit(-1);  }  rcv_max_pkt_sz = mss;  if (rcv_max_pkt_sz == 0 || rcv_max_pkt_sz == 1448 )     rcv_max_pkt_sz = 1472;   /* Make it Ethernet sized MTU */  else    rcv_max_pkt_sz = mss+12;  sigstruct.sa_handler = sig_alrm ;  sigemptyset(&sigstruct.sa_mask);  sigstruct.sa_flags = 0 ;  #ifdef SA_INTERRUPT    sigstruct.sa_flags |= SA_INTERRUPT ;  #endif  sigaction(SIGALRM , &sigstruct,NULL );  expireat.it_value.tv_sec = 60 ; /* RECEIVER ABORTS TIME */  expireat.it_value.tv_usec = 0 ;  expireat.it_interval.tv_sec = 0 ;   expireat.it_interval.tv_usec = 0 ;  setitimer(ITIMER_REAL, &expireat,NULL);  /* receive sender max_pkt_sz */  while ((snd_max_pkt_sz = recv_ctr_mesg(sock_tcp, ctr_buff)) == -1);  if ( snd_max_pkt_sz == -2 )  {    printf("pathload_snd did not respond for 60 sec\n");    close(sock_tcp);    exit(-1);  }  expireat.it_value.tv_sec = 0 ;   expireat.it_value.tv_usec = 0 ;  expireat.it_interval.tv_sec = 0 ;   expireat.it_interval.tv_usec = 0 ;  setitimer(ITIMER_REAL, &expireat,NULL);    sigstruct.sa_handler = SIG_DFL ;  sigemptyset(&sigstruct.sa_mask);  sigstruct.sa_flags = 0 ;  sigaction(SIGALRM , &sigstruct,NULL );  send_ctr_mesg(ctr_buff, rcv_max_pkt_sz);  max_pkt_sz = (rcv_max_pkt_sz < snd_max_pkt_sz) ? rcv_max_pkt_sz:snd_max_pkt_sz ;  if (Verbose)    printf("  Maximum packet size          :: %ld bytes\n",max_pkt_sz);  fprintf(pathload_fp,"  Maximum packet size          :: %ld bytes\n",max_pkt_sz);  rcv_latency = (l_int32) recvfrom_latency(rcv_udp_addr);  while ((snd_latency = recv_ctr_mesg(sock_tcp, ctr_buff)) == -1);  if (Verbose)  {    printf("  send latency @sndr           :: %ld usec\n",snd_latency);    printf("  recv latency @rcvr           :: %ld usec\n",rcv_latency);  }  fprintf(pathload_fp,"  send latency @sndr           :: %ld usec\n",snd_latency);  fprintf(pathload_fp,"  recv latency @rcvr           :: %ld usec\n",rcv_latency);  min_time_interval=      SCALE_FACTOR*((rcv_latency>snd_latency)?rcv_latency:snd_latency) ;  min_time_interval = min_time_interval>MIN_TIME_INTERVAL?      min_time_interval:MIN_TIME_INTERVAL;  if (Verbose)    printf("  Minimum packet spacing       :: %ld usec\n",min_time_interval );  fprintf(pathload_fp,"  Minimum packet spacing       :: %ld usec\n",min_time_interval );  max_rate = (max_pkt_sz+28) * 8. / min_time_interval ;  min_rate = (MIN_PKT_SZ+28) * 8./ MAX_TIME_INTERVAL ;  if(Verbose)    printf("  Max rate(max_pktsz/min_time) :: %.2fMbps\n",max_rate);  fprintf(pathload_fp,"  Max rate(max_pktsz/min_time) :: %.2fMbps\n",max_rate);  /* Estimate ADR */  adr = get_adr() ;  if ( bw_resol == 0 && adr != 0 )    bw_resol = .02*adr ;  else if (bw_resol == 0 )    bw_resol = 2 ;   if(Verbose)    printf("  Grey bandwidth resolution    :: %.2f\n",grey_bw_resolution());  fprintf(pathload_fp,"  Grey bandwidth resolution    :: %.2f\n",grey_bw_resolution());    if (interrupt_coalescence)  {    bw_resol = .05*adr;    if(verbose||Verbose)      printf("  Interrupt coalescion detected\n");    fprintf(pathload_fp,"  Interrupt coalescion detected\n");  }    if ( adr == 0 || adr > max_rate || adr < min_rate)    tr = (max_rate+min_rate)/2.;  else     tr = adr ;  /* Estimate the available bandwidth.*/  transmission_rate = (l_uint32)rint(1000000 * tr);  max_rate_flag = 0 ;  min_rate_flag = 0 ;   fflush(pathload_fp);  sigemptyset(&sigstruct.sa_mask);  sigstruct.sa_handler = sig_alrm ;  sigstruct.sa_flags = 0 ;  #ifdef SA_INTERRUPT    sigstruct.sa_flags |= SA_INTERRUPT ;  #endif  sigaction(SIGALRM , &sigstruct,NULL );  if ( requested_delay )  {    expireat.it_value.tv_sec = requested_delay ; /* RECEIVER ABORTS TIME */    expireat.it_value.tv_usec = 0 ;    expireat.it_interval.tv_sec = 0 ;     expireat.it_interval.tv_usec = 0 ;    setitimer(ITIMER_REAL, &expireat,NULL);  }  while (1)  {    if ( calc_param() == -1 )    {      ctr_code = TERMINATE | CTR_CODE;      send_ctr_mesg(ctr_buff, ctr_code);      terminate_gracefully(exp_start_time) ;    }    send_ctr_mesg(ctr_buff, transmission_rate);    send_ctr_mesg(ctr_buff,cur_pkt_sz) ;    if ( increase_stream_len )      stream_len=3*STREAM_LEN;    else      stream_len = STREAM_LEN;    send_ctr_mesg(ctr_buff,stream_len);    send_ctr_mesg(ctr_buff,time_interval);    ctr_code = SEND_FLEET | CTR_CODE ;    send_ctr_mesg(ctr_buff, ctr_code);    while (1)    {      ret_val = recv_ctr_mesg(sock_tcp, ctr_buff);      if ((((ret_val & CTR_CODE) >> 31) == 1) &&               ((ret_val & 0x7fffffff) == RECV_FLEET ))         break ;      else if ( (((ret_val & CTR_CODE) >> 31) == 1) &&                     ((ret_val & 0x7fffffff) == FINISHED_STREAM ))         ret_val = recv_ctr_mesg(sock_tcp, ctr_buff);    }    if (recv_fleet() == -1)    {      if ( !increase_stream_len )      {        trend = INCREASING;        if ( exp_flag == 1 && prev_trend != 0 && prev_trend != trend)          exp_flag = 0;        prev_trend = trend;        if (rate_adjustment(INCREASING) == -1)          terminate_gracefully(exp_start_time);      }    }    else    {      get_sending_rate() ;      trend = aggregate_trend_result();            if ( trend == -1 && bad_fleet_cs && retry_fleet_cnt_cs >NUM_RETRY_CS )        terminate_gracefully(exp_start_time) ;      else if(( trend == -1 && bad_fleet_cs && retry_fleet_cnt_cs <= NUM_RETRY_CS )) /* repeat fleet with current rate. */        continue ;      if (trend != GREY)      {        if (exp_flag == 1 && prev_trend != 0 && prev_trend != trend)          exp_flag = 0;        prev_trend = trend;      }      if (rate_adjustment(trend) == -1)        terminate_gracefully(exp_start_time);    }    fflush(pathload_fp);  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -