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