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]); 6914ca1249SShuo Chen std::string message = getMessage(); 7014ca1249SShuo Chen printf("message size = %zd\n", message.size()); 71d42543f4SShuo Chen return 0; 72d42543f4SShuo Chen } 73d42543f4SShuo Chen 7493e5f6a7SShuo Chen std::thread(measure).detach(); 75d42543f4SShuo Chen 76d42543f4SShuo Chen int port = atoi(argv[2]); 77d42543f4SShuo Chen if (strcmp(argv[1], "-l") == 0) 7893e5f6a7SShuo Chen { 7924ca08a8SShuo Chen InetAddress listenAddr(port); 8024ca08a8SShuo Chen Acceptor acceptor(listenAddr); 81d42543f4SShuo Chen printf("Accepting... Ctrl-C to exit\n"); 82d42543f4SShuo Chen int count = 0; 83d42543f4SShuo Chen while (true) 84d42543f4SShuo Chen { 85d42543f4SShuo Chen TcpStreamPtr tcpStream = acceptor.accept(); 86d42543f4SShuo Chen printf("accepted no. %d client\n", ++count); 8793e5f6a7SShuo Chen 88d42543f4SShuo Chen std::thread thr(chargen, std::move(tcpStream)); 89d42543f4SShuo Chen thr.detach(); 90d42543f4SShuo Chen } 91d42543f4SShuo Chen } 92d42543f4SShuo Chen else 93d42543f4SShuo Chen { 9424ca08a8SShuo Chen InetAddress addr; 95d42543f4SShuo Chen const char* hostname = argv[1]; 9624ca08a8SShuo Chen if (InetAddress::resolve(hostname, port, &addr)) 97d42543f4SShuo Chen { 98d42543f4SShuo Chen TcpStreamPtr stream(TcpStream::connect(addr)); 99d42543f4SShuo Chen if (stream) 100d42543f4SShuo Chen { 101d42543f4SShuo Chen chargen(std::move(stream)); 102d42543f4SShuo Chen } 103d42543f4SShuo Chen else 104d42543f4SShuo Chen { 105d42543f4SShuo Chen printf("Unable to connect %s\n", addr.toIpPort().c_str()); 106d42543f4SShuo Chen perror(""); 107d42543f4SShuo Chen } 108d42543f4SShuo Chen } 109d42543f4SShuo Chen else 110d42543f4SShuo Chen { 111d42543f4SShuo Chen printf("Unable to resolve %s\n", hostname); 112d42543f4SShuo Chen } 11393e5f6a7SShuo Chen } 11493e5f6a7SShuo Chen} 115