discard.cc revision 24ca08a8
1726c52daSShuo Chen#include "thread/Atomic.h" 2726c52daSShuo Chen#include "datetime/Timestamp.h" 3d42543f4SShuo Chen#include "Acceptor.h" 4d42543f4SShuo Chen#include "InetAddress.h" 5d42543f4SShuo Chen#include "TcpStream.h" 6d42543f4SShuo Chen 7d42543f4SShuo Chen#include <string.h> 8d42543f4SShuo Chen 9d42543f4SShuo Chen#include <thread> 10d42543f4SShuo Chen 11d42543f4SShuo Chenmuduo::AtomicInt64 g_bytes; 12d42543f4SShuo Chen 13d42543f4SShuo Chenvoid measure() 14d42543f4SShuo Chen{ 15d42543f4SShuo Chen muduo::Timestamp start = muduo::Timestamp::now(); 16d42543f4SShuo Chen while (true) 17d42543f4SShuo Chen { 18d42543f4SShuo Chen struct timespec ts = { 1, 0 }; 19d42543f4SShuo Chen ::nanosleep(&ts, NULL); 20d42543f4SShuo Chen // unfortunately, those two assignments are not atomic 21d42543f4SShuo Chen int64_t bytes = g_bytes.getAndSet(0); 22d42543f4SShuo Chen muduo::Timestamp end = muduo::Timestamp::now(); 23d42543f4SShuo Chen double elapsed = timeDifference(end, start); 24d42543f4SShuo Chen start = end; 25d42543f4SShuo Chen if (bytes) 26d42543f4SShuo Chen { 27d42543f4SShuo Chen printf("%.3f MiB/s\n", bytes / (1024.0 * 1024) / elapsed); 28d42543f4SShuo Chen } 29d42543f4SShuo Chen } 30d42543f4SShuo Chen} 31d42543f4SShuo Chen 32d42543f4SShuo Chenvoid discard(TcpStreamPtr stream) 33d42543f4SShuo Chen{ 34d42543f4SShuo Chen char buf[65536]; 35d42543f4SShuo Chen while (true) 36d42543f4SShuo Chen { 37d42543f4SShuo Chen int nr = stream->receiveSome(buf, sizeof buf); 38d42543f4SShuo Chen if (nr <= 0) 39d42543f4SShuo Chen break; 40d42543f4SShuo Chen g_bytes.add(nr); 41d42543f4SShuo Chen } 42d42543f4SShuo Chen} 43d42543f4SShuo Chen 44d42543f4SShuo Chen// a thread-per-connection current discard server and client 45d42543f4SShuo Chenint main(int argc, char* argv[]) 46d42543f4SShuo Chen{ 47d42543f4SShuo Chen if (argc < 3) 48d42543f4SShuo Chen { 4924ca08a8SShuo Chen printf("Usage:\n %s hostname port\n %s -l port [-6]\n", argv[0], argv[0]); 50d42543f4SShuo Chen return 0; 51d42543f4SShuo Chen } 52d42543f4SShuo Chen 53d42543f4SShuo Chen std::thread(measure).detach(); 54d42543f4SShuo Chen 55d42543f4SShuo Chen int port = atoi(argv[2]); 56d42543f4SShuo Chen if (strcmp(argv[1], "-l") == 0) 57d42543f4SShuo Chen { 5824ca08a8SShuo Chen const bool ipv6 = (argc > 3 && strcmp(argv[3], "-6") == 0); 5924ca08a8SShuo Chen Acceptor acceptor((InetAddress(port, ipv6))); 60d42543f4SShuo Chen printf("Accepting... Ctrl-C to exit\n"); 61d42543f4SShuo Chen int count = 0; 62d42543f4SShuo Chen while (true) 63d42543f4SShuo Chen { 64d42543f4SShuo Chen TcpStreamPtr tcpStream = acceptor.accept(); 6524ca08a8SShuo Chen printf("accepted no. %d client: %s <- %s\n", ++count, 6624ca08a8SShuo Chen tcpStream->getLocalAddr().toIpPort().c_str(), 6724ca08a8SShuo Chen tcpStream->getPeerAddr().toIpPort().c_str()); 68d42543f4SShuo Chen 69d42543f4SShuo Chen std::thread thr(discard, std::move(tcpStream)); 70d42543f4SShuo Chen thr.detach(); 71d42543f4SShuo Chen } 72d42543f4SShuo Chen } 73d42543f4SShuo Chen else 74d42543f4SShuo Chen { 7524ca08a8SShuo Chen InetAddress addr; 76d42543f4SShuo Chen const char* hostname = argv[1]; 7724ca08a8SShuo Chen if (InetAddress::resolve(hostname, port, &addr)) 78d42543f4SShuo Chen { 79d42543f4SShuo Chen TcpStreamPtr stream(TcpStream::connect(addr)); 80d42543f4SShuo Chen if (stream) 81d42543f4SShuo Chen { 82d42543f4SShuo Chen discard(std::move(stream)); 83d42543f4SShuo Chen } 84d42543f4SShuo Chen else 85d42543f4SShuo Chen { 86d42543f4SShuo Chen printf("Unable to connect %s\n", addr.toIpPort().c_str()); 87d42543f4SShuo Chen perror(""); 88d42543f4SShuo Chen } 89d42543f4SShuo Chen } 90d42543f4SShuo Chen else 91d42543f4SShuo Chen { 92d42543f4SShuo Chen printf("Unable to resolve %s\n", hostname); 93d42543f4SShuo Chen } 94d42543f4SShuo Chen } 95d42543f4SShuo Chen} 96