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