• tcp网络编程——2


    1.一个服务器只能有一个客户端连接(下面代码)

    ​​​​​​​tcp网络编程(基础)-CSDN博客

    2.一个服务器可以有多个客户端连接(多线程)

    server端创建多个线程,每个线程与不同的client端建立连接。

    -----这里只需要改变下TcpServer.hpp就行了

    1. #pragma once
    2. #include
    3. #include
    4. #include"Socket.hpp"
    5. class TcpServer; //在ThreadData前声明,ThreadData才可以调用TcpServer,否则TcpServer未定义
    6. class ThreadData
    7. {
    8. public:
    9. ThreadData(Socket* s, TcpServer* t, std::string& clientip, uint16_t port)
    10. :sockp(s)
    11. ,tcp_this(t)
    12. ,_clientip(clientip)
    13. ,_port(port)
    14. {}
    15. public:
    16. Socket* sockp;
    17. TcpServer* tcp_this;
    18. std::string _clientip;
    19. uint16_t _port;
    20. };
    21. class TcpServer
    22. {
    23. public:
    24. TcpServer(uint16_t port) :_port(port), _listensocket(new TcpSocket())
    25. {
    26. _listensocket->BuildListenSocketMethod(_port, defaultbackflag); //设置为监听状态
    27. }
    28. static void* Thread_Run(void* args) //根据pthread_create的要求,这个函数的参数只能是void*,并且只有一个,所以用static
    29. {
    30. pthread_detach(pthread_self()); //将线程设置为分离状态,主线程就不用阻塞等待(join)子线程
    31. ThreadData* td = static_cast(args);
    32. char bufferin[1024];
    33. while(true)
    34. {
    35. ssize_t n = recv(td->sockp->GetSockfd(), bufferin, sizeof(bufferin)-1, 0); //接收client发送的信息
    36. //ssize_t n = (s->GetSockfd(), bufferin, sizeof(bufferin)-1);
    37. if(n > 0)
    38. {
    39. bufferin[n] = 0;
    40. std::string ret;
    41. ret += td->_clientip;
    42. ret += " ";
    43. ret += std::to_string(td->_port);
    44. std::cout << ret << " " << "client say#" << bufferin << std::endl;
    45. }
    46. else
    47. {
    48. break;
    49. }
    50. }
    51. return nullptr;
    52. }
    53. void Loop()
    54. {
    55. //client的ip,port
    56. std::string peerip;
    57. uint16_t peerport;
    58. while(true)
    59. {
    60. Socket* s = _listensocket->AcceptConnection(&peerip, &peerport); //服务端接收客户端发来的连接请求
    61. if(s == nullptr) exit(0);
    62. std::cout << "accept success" << std::endl;
    63. //创建线程
    64. pthread_t id;
    65. ThreadData* td = new ThreadData(s, this, peerip, peerport);
    66. pthread_create(&id, nullptr, Thread_Run, td); //我们传结构体给Thread_Run函数
    67. //我们不能join去回收,我们采取将子线程分离(pthread_detach)方式
    68. //原因:join会阻塞等待,如果有新的客户端想连接(connect)服务端,而server在join阻塞,并没有accept,导致connect失败
    69. // ssize_t n = recv(s->GetSockfd(), bufferin, sizeof(bufferin)-1, 0); //接收client发送的信息
    70. // //ssize_t n = (s->GetSockfd(), bufferin, sizeof(bufferin)-1);
    71. // if(n > 0)
    72. // {
    73. // bufferin[n] = 0;
    74. // std::string ret;
    75. // ret += peerip;
    76. // ret += " ";
    77. // ret += std::to_string(peerport);
    78. // std::cout << ret << " " << "client say#" << bufferin << std::endl;
    79. // }
    80. // else
    81. // {
    82. // break;
    83. // }
    84. }
    85. }
    86. ~TcpServer()
    87. {
    88. delete _listensocket;
    89. }
    90. private:
    91. int _port;
    92. Socket* _listensocket;
    93. };

  • 相关阅读:
    Java中灵活使用Mockito
    Ubuntu apt PPA源的定义及相关操作(搜索线上PPA源、查看本地PPA源、添加、修改、删除)
    Tensorflow模型各部分自定义方式
    身体是革命的本钱,希望大家编程之余努力搞好身体
    Nacos源码阅读心得
    Python入门之控制结构 - 顺序与选择结构
    结构体内存对齐详解
    搜索技术【广度优先搜索】 - 双向广度优先搜索 【HDU No. 3085】魔鬼II Nightmare Ⅱ
    MySQL学习笔记-8. 数据库高并发、高性能的基本保证--如何解决数据库超大容量
    2069. 模拟行走机器人 II
  • 原文地址:https://blog.csdn.net/Pursue_Harmony/article/details/137893502