1569528b0SShuo Chen#include "InetAddress.h" 2569528b0SShuo Chen#include "TcpStream.h" 3569528b0SShuo Chen 4569528b0SShuo Chen#include <string.h> 5569528b0SShuo Chen#include <sys/time.h> 6569528b0SShuo Chen#include <unistd.h> 7569528b0SShuo Chen 8569528b0SShuo Chendouble now() 9569528b0SShuo Chen{ 10569528b0SShuo Chen struct timeval tv = { 0, 0 }; 11569528b0SShuo Chen gettimeofday(&tv, NULL); 12569528b0SShuo Chen return tv.tv_sec + tv.tv_usec / 1000000.0; 13569528b0SShuo Chen} 14569528b0SShuo Chen 15569528b0SShuo Chenint main(int argc, char* argv[]) 16569528b0SShuo Chen{ 17569528b0SShuo Chen if (argc < 3) 18569528b0SShuo Chen { 19b42ce01eSShuo Chen printf("Usage: %s [-b] [-D] [-n num] hostname message_length\n", argv[0]); 20b42ce01eSShuo Chen printf(" -b Buffering request before sending.\n" 21b42ce01eSShuo Chen " -D Set TCP_NODELAY.\n" 22b42ce01eSShuo Chen " -n num Send num concurrent requests, default = 1.\n"); 23569528b0SShuo Chen return 0; 24569528b0SShuo Chen } 25569528b0SShuo Chen 26569528b0SShuo Chen int opt = 0; 27569528b0SShuo Chen bool buffering = false; 28569528b0SShuo Chen bool tcpnodelay = false; 29b42ce01eSShuo Chen int num = 1; 30b42ce01eSShuo Chen while ( (opt = getopt(argc, argv, "bDn:")) != -1) 31569528b0SShuo Chen { 32569528b0SShuo Chen switch (opt) 33569528b0SShuo Chen { 34569528b0SShuo Chen case 'b': 35569528b0SShuo Chen buffering = true; 36569528b0SShuo Chen break; 37569528b0SShuo Chen case 'D': 38569528b0SShuo Chen tcpnodelay = true; 39569528b0SShuo Chen break; 40b42ce01eSShuo Chen case 'n': 41b42ce01eSShuo Chen num = atoi(optarg); 42b42ce01eSShuo Chen break; 43569528b0SShuo Chen default: 44569528b0SShuo Chen printf("Unknown option '%c'\n", opt); 45569528b0SShuo Chen return 0; 46569528b0SShuo Chen } 47569528b0SShuo Chen } 48569528b0SShuo Chen 49569528b0SShuo Chen if (optind > argc - 2) 50569528b0SShuo Chen { 51569528b0SShuo Chen printf("Please specify hostname and message_length.\n"); 52569528b0SShuo Chen return 0; 53569528b0SShuo Chen } 54569528b0SShuo Chen 55569528b0SShuo Chen const char* hostname = argv[optind]; 56569528b0SShuo Chen int len = atoi(argv[optind+1]); 57569528b0SShuo Chen 5824ca08a8SShuo Chen const uint16_t port = 3210; 5924ca08a8SShuo Chen InetAddress addr; 6024ca08a8SShuo Chen if (!InetAddress::resolve(hostname, port, &addr)) 61569528b0SShuo Chen { 62569528b0SShuo Chen printf("Unable to resolve %s\n", argv[1]); 63569528b0SShuo Chen return 0; 64569528b0SShuo Chen } 65569528b0SShuo Chen 66569528b0SShuo Chen printf("connecting to %s\n", addr.toIpPort().c_str()); 67569528b0SShuo Chen TcpStreamPtr stream(TcpStream::connect(addr)); 68569528b0SShuo Chen if (!stream) 69569528b0SShuo Chen { 70569528b0SShuo Chen printf("Unable to connect %s\n", addr.toIpPort().c_str()); 71569528b0SShuo Chen perror(""); 72569528b0SShuo Chen return 0; 73569528b0SShuo Chen } 74569528b0SShuo Chen 75569528b0SShuo Chen if (tcpnodelay) 76569528b0SShuo Chen { 77569528b0SShuo Chen stream->setTcpNoDelay(true); 78569528b0SShuo Chen printf("connected, set TCP_NODELAY\n"); 79569528b0SShuo Chen } 80569528b0SShuo Chen else 81569528b0SShuo Chen { 82569528b0SShuo Chen stream->setTcpNoDelay(false); 83569528b0SShuo Chen printf("connected\n"); 84569528b0SShuo Chen } 85569528b0SShuo Chen 86569528b0SShuo Chen 87569528b0SShuo Chen double start = now(); 88b42ce01eSShuo Chen for (int n = 0; n < num; ++n) 89569528b0SShuo Chen { 90b42ce01eSShuo Chen printf("Request no. %d, sending %d bytes\n", n, len); 91b42ce01eSShuo Chen if (buffering) 92b42ce01eSShuo Chen { 93b42ce01eSShuo Chen std::vector<char> message(len + sizeof len, 'S'); 94b42ce01eSShuo Chen memcpy(message.data(), &len, sizeof len); 95b42ce01eSShuo Chen int nw = stream->sendAll(message.data(), message.size()); 96b42ce01eSShuo Chen printf("%.6f sent %d bytes\n", now(), nw); 97b42ce01eSShuo Chen } 98b42ce01eSShuo Chen else 99b42ce01eSShuo Chen { 100b42ce01eSShuo Chen stream->sendAll(&len, sizeof len); 101b42ce01eSShuo Chen printf("%.6f sent header\n", now()); 102b42ce01eSShuo Chen usleep(1000); // prevent kernel merging TCP segments 103b42ce01eSShuo Chen std::string payload(len, 'S'); 104b42ce01eSShuo Chen int nw = stream->sendAll(payload.data(), payload.size()); 105b42ce01eSShuo Chen printf("%.6f sent %d bytes\n", now(), nw); 106b42ce01eSShuo Chen } 107569528b0SShuo Chen } 108b42ce01eSShuo Chen 109b42ce01eSShuo Chen printf("Sent all %d requests, receiving responses.\n", num); 110b42ce01eSShuo Chen for (int n = 0; n < num; ++n) 111569528b0SShuo Chen { 112b42ce01eSShuo Chen int ack = 0; 113b42ce01eSShuo Chen int nr = stream->receiveAll(&ack, sizeof ack); 114b42ce01eSShuo Chen printf("%.6f received %d bytes, ack = %d\n", now(), nr, ack); 115569528b0SShuo Chen } 116b42ce01eSShuo Chen printf("total %f seconds\n", now() - start); 117569528b0SShuo Chen} 118