tp.c
calculate throughput
1 /* gput.c: out.tr¤ò²òÀϤ·¤Æ¥¹¥ë¡¼¥×¥Ã¥ÈÆÃÀ¤ò·×»»¤¹¤ë 2 * out.et¤ò²òÀϤ·¤ÆºÆÁ÷¥¿¥¤¥à¥¢¥¦¥È¤ÎȯÀ¸Í̵¤ò³Îǧ¤¹¤ë 3 * gput <trace file> <event trace file > <required node> <granlarity> 4 * (e.g.,) ./gput out.tr out.et 1 1.0 > goodput.dat 5 * last line output: <goodput>Mbps <isIncast> <transmitted bytes>Byte \ 6 * <transmission time>s <first_recv_time>s <last_recv_time>s 7 * <isIncast>: 0 = fales (not incast); 1 = true (incast) 8 */ 9 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 14 #define MAXFLOW 128 15 #define SW_NODE 0 16 17 typedef struct rcvd_t { 18 int seqno; 19 int flow_id; 20 struct rcvd_t *next; 21 } rcvd_t; 22 23 rcvd_t head; 24 25 int isnew (int seqno, int flow_id) 26 { 27 rcvd_t *rcvd = head.next; 28 29 while ( rcvd ){ 30 if ( rcvd->seqno == seqno && rcvd->flow_id == flow_id ) return 0; 31 rcvd = rcvd->next; 32 } 33 34 // true 35 return 1; 36 } 37 38 void updatercvd (int seqno, int flow_id) 39 { 40 rcvd_t *rcvd; 41 42 if ( NULL == (rcvd = (rcvd_t *)malloc(sizeof(rcvd_t))) ) { 43 fprintf(stderr, "Memory Allocation Error.\n"); 44 exit(1); 45 } 46 47 rcvd->seqno = seqno; 48 rcvd->flow_id = flow_id; 49 rcvd->next = head.next; 50 head.next = rcvd; 51 } 52 53 void freercvd (rcvd_t *rcvd) 54 { 55 if (rcvd->next) freercvd(rcvd->next); 56 free(rcvd); 57 rcvd = NULL; 58 } 59 60 int main ( int argc, char **argv ) 61 { 62 FILE *fp_ns, *fp_et; 63 int tx, rx, packet_size, flow_id, sequence, packet_id, 64 node, cwnd; 65 unsigned long int sum,sum_all; 66 char buffer[128], event, packet_type[8], flags[8], tx_address[16], 67 rx_address[16], event_type[32], is_rto; 68 double time, clock, granularity, first_recv_time, last_recv_time, throughput; 69 double last_sent_time[MAXFLOW]; 70 71 // Init 72 head.next = NULL; 73 first_recv_time = 100000.0; 74 last_recv_time = -1.0; 75 int i; 76 for(i = 0; i < MAXFLOW; i++) last_sent_time[i] = -1.0; 77 78 // Open Trace file (out.ns) 79 if ( NULL == ( fp_ns = fopen ( argv[1], "r" ) ) ) { 80 fprintf ( stderr, "Can't open %s\n", argv[1] ); 81 return 1; 82 } 83 84 // Open Event Trace file (out.et) 85 if ( NULL == ( fp_et = fopen ( argv[2], "r" ) ) ) { 86 fprintf ( stderr, "Can't open %s\n", argv[2] ); 87 return 1; 88 } 89 90 node = atoi ( argv[3] ); 91 granularity = atof ( argv[4] ); 92 93 // Goodput Calculation 94 for ( sum = 0, sum_all = 0, clock = 0.0; feof ( fp_ns ) == 0; ) { 95 /* 1¹Ôʬ¤Î¥Ç¡¼¥¿¤ò²òÀÏ */ 96 fgets ( buffer, 128, fp_ns ); 97 sscanf ( buffer, "%c %lf %d %d %s %d %s %d %s %s %d %d", 98 &event, &time, &tx, &rx, packet_type, &packet_size, flags, &flow_id, 99 tx_address, rx_address, &sequence, &packet_id ); 100 101 /* ³ºÅö¤¹¤ë¥Ç¡¼¥¿¥é¥¤¥ó¤«³Îǧ¤¹¤ë */ 102 // exception check 103 if ( flow_id >= MAXFLOW ) { 104 printf("MAXFLOW ERROR! flow_id:%d\n", flow_id); 105 return 1; 106 } 107 108 // for counting retransmission timeout 109 if ( event == '+' && rx == SW_NODE 110 && last_sent_time[flow_id] < time ) 111 last_sent_time[flow_id] = time; 112 113 // for calculating goodput 114 if ( event != 'r' ) continue; 115 if ( strcmp(packet_type, "tcp") != 0 ) continue; 116 if ( rx != node ) continue; 117 118 /* ¥¹¥ë¡¼¥×¥Ã¥È¤Î·×»» Mbps*/ 119 if ( ( time - clock ) > granularity ) { 120 throughput = ( (double) sum / granularity ) * 8.0 / 1000.0 / 1000.0; 121 clock += granularity; 122 printf ( "%f\t%f\t%d\n", clock, throughput, sum ); 123 sum = 0; 124 } 125 126 // is newdata? (uncount unnecessary restransmission) 127 if ( isnew(sequence, flow_id) ){ 128 updatercvd(sequence, flow_id); 129 if ( first_recv_time > time) first_recv_time = time; 130 last_recv_time = time; 131 sum += packet_size; 132 sum_all += (unsigned long int)packet_size; 133 } 134 } // for 135 136 throughput = ( (double) sum_all / (last_recv_time - first_recv_time) ) 137 * 8.0 / 1000.0 / 1000.0; 138 139 // Count Retransmisson Timeout Event from Event Trace file 140 for ( is_rto = 0; feof ( fp_et ) == 0; ) { 141 /* 1¹Ôʬ¤Î¥Ç¡¼¥¿¤ò²òÀÏ */ 142 fgets ( buffer, 128, fp_et ); 143 sscanf ( buffer, "%c %lf %d %d %s %s %d %d %d", 144 &event, &time, &tx, &rx, packet_type, event_type, &flow_id, 145 &sequence, &cwnd ); 146 147 if ( time > last_sent_time[flow_id] ) continue; 148 if ( strcmp(event_type, "TIMEOUT") == 0 ) is_rto = 1; 149 } 150 151 printf ( "%f\t%d\t%u\t%f\t%f\t%f\n", 152 throughput, is_rto, sum_all, last_recv_time - first_recv_time, 153 first_recv_time, last_recv_time); 154 155 fclose ( fp_ns ); 156 fclose ( fp_et ); 157 158 freercvd( head.next ); 159 160 return 0; 161 } 162