pingpong_client.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "hv/hmain.h"
  2. #include "hv/hloop.h"
  3. #include "hv/hsocket.h"
  4. #include "hv/EventLoopThreadPool.h"
  5. using namespace hv;
  6. static const char options[] = "hH:p:c:t:s:";
  7. static const char detail_options[] = R"(
  8. -h Print help
  9. -H <Host> default 127.0.0.1
  10. -p <port>
  11. -t <threads> default 4
  12. -c <connections> default 1000
  13. -s <seconds> default 10
  14. -b <bytes> send buffer size, default 8192
  15. )";
  16. static const char* host = "127.0.0.1";
  17. static int port = 0;
  18. static int threads = 4;
  19. static int connections = 1000;
  20. static int seconds = 10;
  21. static int sendbytes = 1024;
  22. static void* sendbuf = NULL;
  23. static std::atomic<int> connected_num(0);
  24. static std::atomic<int> disconnected_num(0);
  25. static std::atomic<uint64_t> total_readcount(0);
  26. static std::atomic<uint64_t> total_readbytes(0);
  27. static void print_help() {
  28. printf("Usage: %s [%s]\n", g_main_ctx.program_name, options);
  29. printf("Options:\n%s\n", detail_options);
  30. }
  31. static void print_result() {
  32. printf("total readcount=%llu readbytes=%llu\n",
  33. (unsigned long long)total_readcount,
  34. (unsigned long long)total_readbytes);
  35. printf("throughput = %llu MB/s\n", (total_readbytes) / ((unsigned long long)seconds * 1024 * 1024));
  36. }
  37. static void on_close(hio_t* io) {
  38. if (++disconnected_num == connections) {
  39. printf("all disconnected\n");
  40. }
  41. }
  42. void on_recv(hio_t* io, void* buf, int readbytes) {
  43. ++total_readcount;
  44. total_readbytes += readbytes;
  45. hio_write(io, buf, readbytes);
  46. }
  47. static void on_connect(hio_t* io) {
  48. if (++connected_num == connections) {
  49. printf("all connected\n");
  50. }
  51. tcp_nodelay(hio_fd(io), 1);
  52. hio_setcb_read(io, on_recv);
  53. hio_setcb_close(io, on_close);
  54. hio_read_start(io);
  55. hio_write(io, sendbuf, sendbytes);
  56. }
  57. int main(int argc, char** argv) {
  58. // parse cmdline
  59. main_ctx_init(argc, argv);
  60. int ret = parse_opt(argc, argv, options);
  61. if (ret != 0) {
  62. print_help();
  63. exit(ret);
  64. }
  65. const char* strHost = get_arg("H");
  66. const char* strPort = get_arg("p");
  67. const char* strThreads = get_arg("t");
  68. const char* strConnections = get_arg("c");
  69. const char* strSeconds = get_arg("s");
  70. const char* strBytes = get_arg("b");
  71. if (strHost) host = strHost;
  72. if (strPort) port = atoi(strPort);
  73. if (strThreads) threads = atoi(strThreads);
  74. if (strConnections) connections = atoi(strConnections);
  75. if (strSeconds) seconds = atoi(strSeconds);
  76. if (strBytes) sendbytes = atoi(strBytes);
  77. if (get_arg("h") || port == 0) {
  78. print_help();
  79. exit(0);
  80. }
  81. sendbuf = malloc(sendbytes);
  82. printf("[%s:%d] %d threads %d connections run %ds\n",
  83. host, port,
  84. threads, connections, seconds);
  85. EventLoopThreadPool loop_threads(threads);
  86. loop_threads.start(true);
  87. for (int i = 0; i < connections; ++i) {
  88. EventLoopPtr loop = loop_threads.nextLoop();
  89. loop->runInLoop(std::bind(hloop_create_tcp_client, loop->loop(), host, port, on_connect));
  90. }
  91. // stop after seconds
  92. loop_threads.loop()->setTimeout(seconds * 1000, [&loop_threads](TimerID timerID){
  93. loop_threads.stop(false);
  94. });
  95. // wait loop_threads exit
  96. loop_threads.join();
  97. print_result();
  98. return 0;
  99. }