@@ -24,21 +24,24 @@ class BandwidthReporter
2424
2525 void reportDelta (double now, int64_t total_bytes)
2626 {
27- report (now, total_bytes, total_bytes - last_bytes_, now - last_time_);
27+ report (now, total_bytes - last_bytes_, now - last_time_);
2828 last_time_ = now;
2929 last_bytes_ = total_bytes;
3030 }
3131
32- void reportAll (double now, int64_t total_bytes)
32+ void reportAll (double now, int64_t total_bytes, int64_t syscalls )
3333 {
34- report (now, total_bytes, total_bytes, now);
34+ printf (" Transferred %.3fMB %.3fMiB in %.3fs, %lld syscalls, %.1f Bytes/syscall\n " ,
35+ total_bytes / 1e6 , total_bytes / (1024.0 * 1024 ), now, (long long )syscalls,
36+ total_bytes * 1.0 / syscalls);
37+ report (now, total_bytes, now);
3538 }
3639
3740 private:
38- void report (double now, int64_t total_bytes, int64_t bytes, double elapsed)
41+ void report (double now, int64_t bytes, double elapsed)
3942 {
40- printf ( " %6.3f %.3fM %.3fM/s " , now, total_bytes / 1e6 ,
41- elapsed > 0 ? bytes / 1e6 / elapsed : 0.0 );
43+ double mbps = elapsed > 0 ? bytes / 1e6 / elapsed : 0.0 ;
44+ printf ( " %6.3f %6.2fMB/s %6.1fMbits/s " , now, mbps, mbps* 8 );
4245 if (sender_)
4346 printSender ();
4447 else
@@ -108,21 +111,26 @@ void runClient(const InetAddress& serverAddr, int64_t bytes_limit, double durati
108111 perror (" " );
109112 return ;
110113 }
114+ printf (" Connected %s -> %s\n " , stream->getLocalAddr ().toIpPort ().c_str (),
115+ stream->getPeerAddr ().toIpPort ().c_str ());
111116
112117 const Timestamp start = Timestamp::now ();
113118 const int block_size = 64 * 1024 ;
114119 std::string message (block_size, ' S' );
115120 int seconds = 1 ;
116121 int64_t total_bytes = 0 ;
122+ int64_t syscalls = 0 ;
117123 double elapsed = 0 ;
118124 BandwidthReporter rpt (stream->fd (), true );
119- rpt.reportAll (0 , 0 );
125+ rpt.reportDelta (0 , 0 );
120126
121127 while (total_bytes < bytes_limit) {
122- int nw = stream->sendAll (message.data (), message.size ());
128+ int bytes = std::min<int64_t >(message.size (), bytes_limit - total_bytes);
129+ int nw = stream->sendSome (message.data (), bytes);
123130 if (nw <= 0 )
124131 break ;
125132 total_bytes += nw;
133+ syscalls++;
126134 elapsed = timeDifference (Timestamp::now (), start);
127135
128136 if (elapsed >= duration)
@@ -146,7 +154,7 @@ void runClient(const InetAddress& serverAddr, int64_t bytes_limit, double durati
146154 printf (" nr = %d\n " , nr);
147155 Timestamp end = Timestamp::now ();
148156 elapsed = timeDifference (end, start);
149- rpt.reportAll (elapsed, total_bytes);
157+ rpt.reportAll (elapsed, total_bytes, syscalls );
150158}
151159
152160void runServer (int port)
@@ -158,22 +166,25 @@ void runServer(int port)
158166 printf (" Accepting on port %d ... Ctrl-C to exit\n " , port);
159167 TcpStreamPtr stream = acceptor.accept ();
160168 ++count;
161- printf (" accepted no. %d client from %s\n " , count,
169+ printf (" accepted no. %d client %s <- %s\n " , count,
170+ stream->getLocalAddr ().toIpPort ().c_str (),
162171 stream->getPeerAddr ().toIpPort ().c_str ());
163172
164173 const Timestamp start = Timestamp::now ();
165174 int seconds = 1 ;
166175 int64_t bytes = 0 ;
176+ int64_t syscalls = 0 ;
167177 double elapsed = 0 ;
168178 BandwidthReporter rpt (stream->fd (), false );
169- rpt.reportAll (elapsed, bytes);
179+ rpt.reportDelta (elapsed, bytes);
170180
171181 char buf[65536 ];
172182 while (true ) {
173183 int nr = stream->receiveSome (buf, sizeof buf);
174184 if (nr <= 0 )
175185 break ;
176186 bytes += nr;
187+ syscalls++;
177188
178189 elapsed = timeDifference (Timestamp::now (), start);
179190 if (elapsed >= seconds) {
@@ -183,41 +194,71 @@ void runServer(int port)
183194 }
184195 }
185196 elapsed = timeDifference (Timestamp::now (), start);
186- rpt.reportAll (elapsed, bytes);
197+ rpt.reportAll (elapsed, bytes, syscalls );
187198 printf (" Client no. %d done\n " , count);
188199 }
189200}
190201
202+ int64_t parseBytes (const char * arg)
203+ {
204+ char * end = NULL ;
205+ int64_t bytes = strtoll (arg, &end, 10 );
206+ switch (*end) {
207+ case ' \0 ' :
208+ return bytes;
209+ case ' k' :
210+ return bytes * 1000 ;
211+ case ' K' :
212+ return bytes * 1024 ;
213+ case ' m' :
214+ return bytes * 1000 * 1000 ;
215+ case ' M' :
216+ return bytes * 1024 * 1024 ;
217+ case ' g' :
218+ return bytes * 1000 * 1000 * 1000 ;
219+ case ' G' :
220+ return bytes * 1024 * 1024 * 1024 ;
221+ default :
222+ return 0 ;
223+ }
224+ }
225+
191226int main (int argc, char * argv[])
192227{
193228 int opt;
194229 bool client = false , server = false ;
195- InetAddress serverAddr;
196- const int port = 2009 ;
230+ std::string serverAddr;
231+ int port = 2009 ;
197232 const int64_t kGigaBytes = 1024 * 1024 * 1024 ;
198233 int64_t bytes_limit = 10 * kGigaBytes ;
199234 double duration = 10 ;
200235
201- while ((opt = getopt (argc, argv, " sc:t:" )) != -1 ) {
236+ while ((opt = getopt (argc, argv, " sc:t:b:p: " )) != -1 ) {
202237 switch (opt) {
203238 case ' s' :
204239 server = true ;
205240 break ;
206241 case ' c' :
207242 client = true ;
208- serverAddr = InetAddress ( optarg, port) ;
243+ serverAddr = optarg;
209244 break ;
210245 case ' t' :
211246 duration = strtod (optarg, NULL );
212247 break ;
248+ case ' b' :
249+ bytes_limit = parseBytes (optarg);
250+ break ;
251+ case ' p' :
252+ port = strtol (optarg, NULL , 10 );
253+ break ;
213254 default :
214255 fprintf (stderr, " Usage: %s FIXME\n " , argv[0 ]);
215256 break ;
216257 }
217258 }
218259
219260 if (client)
220- runClient (serverAddr, bytes_limit, duration);
261+ runClient (InetAddress ( serverAddr, port) , bytes_limit, duration);
221262 else if (server)
222263 runServer (port);
223264}
0 commit comments