飞道的博客

项目(百万并发网络通信架构)9.4---多线程客户端服务端最终代码测试

418人阅读  评论(0)

前言

  • 前面几篇文章改造好了客户端与服务端的代码,本文进行测试
  • 服务端是多线程的,其业务逻辑代码中用到了多线程
  • 客户端的业务逻辑代码不是多线程的,只是其测试代码main函数中用到了多线程

一、测试10000客户端连接

客户端测试代码如下

  • 这个代码在前面文章介绍过,此处只是将客户端的数量cCount变量改为了10000

   
  1. #include "EasyTcpClient.hpp"
  2. #include <thread>
  3. bool g_bRun = false;
  4. const int cCount = 10000; //客户端的数量
  5. const int tCount = 4; //线程的数量
  6. EasyTcpClient* client[cCount]; //客户端的数组
  7. void cmdThread();
  8. void sendThread(int id);
  9. int main()
  10. {
  11. g_bRun = true;
  12. //UI线程,可以输入命令
  13. std:: thread t(cmdThread);
  14. t.detach();
  15. //启动发送线程
  16. for ( int n = 0; n < tCount; ++n)
  17. {
  18. std:: thread t(sendThread, n + 1);
  19. t.detach();
  20. }
  21. while (g_bRun)
  22. Sleep( 100);
  23. /*getchar();
  24. getchar();*/
  25. return 0;
  26. }
  27. void cmdThread()
  28. {
  29. char cmdBuf[ 256] = {};
  30. while ( true)
  31. {
  32. std:: cin >> cmdBuf;
  33. if ( 0 == strcmp(cmdBuf, "exit"))
  34. {
  35. g_bRun = false;
  36. break;
  37. }
  38. else {
  39. std:: cout << "命令不识别,请重新输入" << std:: endl;
  40. }
  41. }
  42. }
  43. void sendThread(int id)
  44. {
  45. /*
  46. 下面这几个变量是为了平均每个线程创建的客户端的数量:
  47. 例如,本次测试时客户端数量为1000,线程数量为4,那么每个线程应该创建250个客户端
  48. 线程1:c=250,begin=0,end=250
  49. 线程2:c=250,begin=250,end=500
  50. 线程3:c=250,begin=500,end=750
  51. 线程4:c=250,begin=750,end=1000
  52. */
  53. int c = cCount / tCount;
  54. int begin = (id - 1)*c;
  55. int end = id*c;
  56. for ( int n = begin; n < end; ++n) //创建客户端
  57. {
  58. client[n] = new EasyTcpClient;
  59. }
  60. for ( int n = begin; n < end; ++n) //让每个客户端连接服务器
  61. {
  62. client[n]->ConnectServer( "192.168.0.105", 4567);
  63. }
  64. printf( "Thread<%d>,Connect=<begin=%d, end=%d>\n", id, (begin + 1), end);
  65. //连接成功之后,等待3秒再去发送数据
  66. std::chrono:: microseconds t(3000);
  67. std::this_thread::sleep_for(t);
  68. //这里定义为数组,可以随根据需求修改客户端单次发送给服务端的数据包数量
  69. const int nNum = 1;
  70. Login login[nNum];
  71. for ( int n = 0; n < nNum; ++n)
  72. {
  73. strcpy(login[n].userName, "dongshao");
  74. strcpy(login[n].PassWord, "123456");
  75. }
  76. //在外面定义nLen,就不用每次在for循环中SendData时还要去sizeof计算一下login的大小
  77. int nLen = sizeof(login);
  78. //循环向服务端发送消息
  79. while (g_bRun)
  80. {
  81. for ( int n = begin; n < end; ++n)
  82. {
  83. client[n]->SendData(login, nLen);
  84. client[n]->Onrun();
  85. }
  86. }
  87. //关闭客户端
  88. for ( int n = begin; n < end; ++n)
  89. {
  90. client[n]->CloseSocket();
  91. delete client[n];
  92. }
  93. printf( "thread<%d>:all clients close the connection!\n");
  94. }

服务端测试代码

  • 因为是10000个客户端连接,因此需要将EasyTcpServer.hpp中的FD_SETSIZE宏定义改为超过10000的数字(此处改为10240)

   
  1. #include "EasyTcpServer.hpp"
  2. #include "MessageHeader.hpp"
  3. int main()
  4. {
  5. EasyTcpServer server;
  6. server.Bind( "192.168.0.105", 4567);
  7. server.Listen( 5);
  8. server.Start( 4);
  9. while (server.isRun())
  10. {
  11. server.Onrun();
  12. }
  13. server.CloseSocket();
  14. std:: cout << "服务端停止工作!" << std:: endl;
  15. getchar(); //防止程序一闪而过
  16. return 0;
  17. }

运行结果

  • 左侧为服务端,显示接收到1000个客户端,每秒接收到的数据为10万左右

二、总结

  • 本文测试了10000个客户端连接服务器,并且客户端与服务端有数据的收发
  • 因为客户端的数量为10000,且客户端与服务端之间有数据的收发,因此网络中传入的数据较多,程序运行一会儿就会卡顿。原因有:
    • 本人的机子性能限制
    • 客户端数量过多,服务端和客户端程序中虽然设计了接收缓冲区(参阅前面的7.x相关文章),但是没有设计发送缓冲区,因此数据交互一会儿后缓冲区膨胀,导致程序会慢慢变卡
  • 在后面的文章中会介绍设计发送缓冲区,待续

转载:https://blog.csdn.net/qq_41453285/article/details/105686356
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场