1#include "InetAddress.h" 2#include "TcpStream.h" 3 4#include <string.h> 5#include <sys/time.h> 6#include <unistd.h> 7 8double now() 9{ 10 struct timeval tv = { 0, 0 }; 11 gettimeofday(&tv, NULL); 12 return tv.tv_sec + tv.tv_usec / 1000000.0; 13} 14 15int main(int argc, char* argv[]) 16{ 17 if (argc < 3) 18 { 19 printf("Usage: %s [-b] [-D] [-n num] hostname message_length\n", argv[0]); 20 printf(" -b Buffering request before sending.\n" 21 " -D Set TCP_NODELAY.\n" 22 " -n num Send num concurrent requests, default = 1.\n"); 23 return 0; 24 } 25 26 int opt = 0; 27 bool buffering = false; 28 bool tcpnodelay = false; 29 int num = 1; 30 while ( (opt = getopt(argc, argv, "bDn:")) != -1) 31 { 32 switch (opt) 33 { 34 case 'b': 35 buffering = true; 36 break; 37 case 'D': 38 tcpnodelay = true; 39 break; 40 case 'n': 41 num = atoi(optarg); 42 break; 43 default: 44 printf("Unknown option '%c'\n", opt); 45 return 0; 46 } 47 } 48 49 if (optind > argc - 2) 50 { 51 printf("Please specify hostname and message_length.\n"); 52 return 0; 53 } 54 55 const char* hostname = argv[optind]; 56 int len = atoi(argv[optind+1]); 57 58 const uint16_t port = 3210; 59 InetAddress addr; 60 if (!InetAddress::resolve(hostname, port, &addr)) 61 { 62 printf("Unable to resolve %s\n", argv[1]); 63 return 0; 64 } 65 66 printf("connecting to %s\n", addr.toIpPort().c_str()); 67 TcpStreamPtr stream(TcpStream::connect(addr)); 68 if (!stream) 69 { 70 printf("Unable to connect %s\n", addr.toIpPort().c_str()); 71 perror(""); 72 return 0; 73 } 74 75 if (tcpnodelay) 76 { 77 stream->setTcpNoDelay(true); 78 printf("connected, set TCP_NODELAY\n"); 79 } 80 else 81 { 82 stream->setTcpNoDelay(false); 83 printf("connected\n"); 84 } 85 86 87 double start = now(); 88 for (int n = 0; n < num; ++n) 89 { 90 printf("Request no. %d, sending %d bytes\n", n, len); 91 if (buffering) 92 { 93 std::vector<char> message(len + sizeof len, 'S'); 94 memcpy(message.data(), &len, sizeof len); 95 int nw = stream->sendAll(message.data(), message.size()); 96 printf("%.6f sent %d bytes\n", now(), nw); 97 } 98 else 99 { 100 stream->sendAll(&len, sizeof len); 101 printf("%.6f sent header\n", now()); 102 usleep(1000); // prevent kernel merging TCP segments 103 std::string payload(len, 'S'); 104 int nw = stream->sendAll(payload.data(), payload.size()); 105 printf("%.6f sent %d bytes\n", now(), nw); 106 } 107 } 108 109 printf("Sent all %d requests, receiving responses.\n", num); 110 for (int n = 0; n < num; ++n) 111 { 112 int ack = 0; 113 int nr = stream->receiveAll(&ack, sizeof ack); 114 printf("%.6f received %d bytes, ack = %d\n", now(), nr, ack); 115 } 116 printf("total %f seconds\n", now() - start); 117} 118