chargen.cc revision 726c52da
1726c52daSShuo Chen#include "thread/Atomic.h" 2726c52daSShuo Chen#include "datetime/Timestamp.h" 393e5f6a7SShuo Chen#include "Acceptor.h" 493e5f6a7SShuo Chen#include "InetAddress.h" 593e5f6a7SShuo Chen#include "TcpStream.h" 693e5f6a7SShuo Chen 7d42543f4SShuo Chen#include <string.h> 8d42543f4SShuo Chen 993e5f6a7SShuo Chen#include <thread> 1093e5f6a7SShuo Chen 1193e5f6a7SShuo Chenmuduo::AtomicInt64 g_bytes; 1293e5f6a7SShuo Chen 1393e5f6a7SShuo Chenstd::string getMessage() 1493e5f6a7SShuo Chen{ 1593e5f6a7SShuo Chen std::string line; 1693e5f6a7SShuo Chen for (int i = 33; i < 127; ++i) 1793e5f6a7SShuo Chen { 1893e5f6a7SShuo Chen line.push_back(char(i)); 1993e5f6a7SShuo Chen } 2093e5f6a7SShuo Chen line += line; 2193e5f6a7SShuo Chen 2293e5f6a7SShuo Chen std::string message; 2393e5f6a7SShuo Chen for (size_t i = 0; i < 127-33; ++i) 2493e5f6a7SShuo Chen { 2593e5f6a7SShuo Chen message += line.substr(i, 72) + '\n'; 2693e5f6a7SShuo Chen } 2793e5f6a7SShuo Chen return message; 2893e5f6a7SShuo Chen} 2993e5f6a7SShuo Chen 3093e5f6a7SShuo Chenvoid measure() 3193e5f6a7SShuo Chen{ 3293e5f6a7SShuo Chen muduo::Timestamp start = muduo::Timestamp::now(); 3393e5f6a7SShuo Chen while (true) 3493e5f6a7SShuo Chen { 3593e5f6a7SShuo Chen struct timespec ts = { 1, 0 }; 3693e5f6a7SShuo Chen ::nanosleep(&ts, NULL); 3793e5f6a7SShuo Chen // unfortunately, those two assignments are not atomic 3893e5f6a7SShuo Chen int64_t bytes = g_bytes.getAndSet(0); 3993e5f6a7SShuo Chen muduo::Timestamp end = muduo::Timestamp::now(); 4093e5f6a7SShuo Chen double elapsed = timeDifference(end, start); 4193e5f6a7SShuo Chen start = end; 4293e5f6a7SShuo Chen if (bytes) 4393e5f6a7SShuo Chen { 4493e5f6a7SShuo Chen printf("%.3f MiB/s\n", bytes / (1024.0 * 1024) / elapsed); 4593e5f6a7SShuo Chen } 4693e5f6a7SShuo Chen } 4793e5f6a7SShuo Chen} 4893e5f6a7SShuo Chen 4993e5f6a7SShuo Chenvoid chargen(TcpStreamPtr stream) 5093e5f6a7SShuo Chen{ 5193e5f6a7SShuo Chen std::string message = getMessage(); 5293e5f6a7SShuo Chen while (true) 5393e5f6a7SShuo Chen { 5493e5f6a7SShuo Chen int nw = stream->sendAll(message.data(), message.size()); 5593e5f6a7SShuo Chen g_bytes.add(nw); 5693e5f6a7SShuo Chen if (nw < static_cast<int>(message.size())) 5793e5f6a7SShuo Chen { 5893e5f6a7SShuo Chen break; 5993e5f6a7SShuo Chen } 6093e5f6a7SShuo Chen } 6193e5f6a7SShuo Chen} 6293e5f6a7SShuo Chen 63d42543f4SShuo Chen// a thread-per-connection current chargen server and client 64d42543f4SShuo Chenint main(int argc, char* argv[]) 6593e5f6a7SShuo Chen{ 66d42543f4SShuo Chen if (argc < 3) 67d42543f4SShuo Chen { 68d42543f4SShuo Chen printf("Usage:\n %s hostname port\n %s -l port\n", argv[0], argv[0]); 69d42543f4SShuo Chen return 0; 70d42543f4SShuo Chen } 71d42543f4SShuo Chen 7293e5f6a7SShuo Chen std::thread(measure).detach(); 73d42543f4SShuo Chen 74d42543f4SShuo Chen int port = atoi(argv[2]); 75d42543f4SShuo Chen if (strcmp(argv[1], "-l") == 0) 7693e5f6a7SShuo Chen { 77d42543f4SShuo Chen Acceptor acceptor((InetAddress(port))); 78d42543f4SShuo Chen printf("Accepting... Ctrl-C to exit\n"); 79d42543f4SShuo Chen int count = 0; 80d42543f4SShuo Chen while (true) 81d42543f4SShuo Chen { 82d42543f4SShuo Chen TcpStreamPtr tcpStream = acceptor.accept(); 83d42543f4SShuo Chen printf("accepted no. %d client\n", ++count); 8493e5f6a7SShuo Chen 85d42543f4SShuo Chen std::thread thr(chargen, std::move(tcpStream)); 86d42543f4SShuo Chen thr.detach(); 87d42543f4SShuo Chen } 88d42543f4SShuo Chen } 89d42543f4SShuo Chen else 90d42543f4SShuo Chen { 91d42543f4SShuo Chen InetAddress addr(port); 92d42543f4SShuo Chen const char* hostname = argv[1]; 93d42543f4SShuo Chen if (InetAddress::resolve(hostname, &addr)) 94d42543f4SShuo Chen { 95d42543f4SShuo Chen TcpStreamPtr stream(TcpStream::connect(addr)); 96d42543f4SShuo Chen if (stream) 97d42543f4SShuo Chen { 98d42543f4SShuo Chen chargen(std::move(stream)); 99d42543f4SShuo Chen } 100d42543f4SShuo Chen else 101d42543f4SShuo Chen { 102d42543f4SShuo Chen printf("Unable to connect %s\n", addr.toIpPort().c_str()); 103d42543f4SShuo Chen perror(""); 104d42543f4SShuo Chen } 105d42543f4SShuo Chen } 106d42543f4SShuo Chen else 107d42543f4SShuo Chen { 108d42543f4SShuo Chen printf("Unable to resolve %s\n", hostname); 109d42543f4SShuo Chen } 11093e5f6a7SShuo Chen } 11193e5f6a7SShuo Chen} 112