tcp网络编程——2

本文介绍了如何使用C++的多线程技术,使一个服务器同时处理多个客户端连接,展示了如何在TcpServer类中创建线程并接收和处理客户端消息。
摘要由CSDN通过智能技术生成

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

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

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

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

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

#pragma once

#include<iostream>
#include<pthread.h>
#include"Socket.hpp"

class TcpServer;  //在ThreadData前声明,ThreadData才可以调用TcpServer,否则TcpServer未定义
class ThreadData
{
public:
    ThreadData(Socket* s, TcpServer* t, std::string& clientip, uint16_t port)
        :sockp(s)
        ,tcp_this(t)
        ,_clientip(clientip)
        ,_port(port)
        {}
public:
    Socket* sockp;
    TcpServer* tcp_this;
    std::string _clientip;
    uint16_t _port;
};

class TcpServer
{
public:
    TcpServer(uint16_t port) :_port(port), _listensocket(new TcpSocket())
    {
        _listensocket->BuildListenSocketMethod(_port, defaultbackflag); //设置为监听状态
    }
    
    static void* Thread_Run(void* args) //根据pthread_create的要求,这个函数的参数只能是void*,并且只有一个,所以用static
    {
        pthread_detach(pthread_self()); //将线程设置为分离状态,主线程就不用阻塞等待(join)子线程
        ThreadData* td = static_cast<ThreadData*>(args);  

        char bufferin[1024];
        while(true)
        {
            ssize_t n = recv(td->sockp->GetSockfd(), bufferin, sizeof(bufferin)-1, 0); //接收client发送的信息
            //ssize_t n = (s->GetSockfd(), bufferin, sizeof(bufferin)-1);
            if(n > 0)
            {
                bufferin[n] = 0;
                std::string ret;
                ret += td->_clientip;
                ret += " ";
                ret += std::to_string(td->_port);
                std::cout << ret << " " << "client say#" << bufferin << std::endl;    
            }
            else
            {
                break;
            }
        }

        return nullptr;
    }

    void Loop()
    {
        //client的ip,port
        std::string peerip;
        uint16_t peerport;

        while(true)
        {

            Socket* s = _listensocket->AcceptConnection(&peerip, &peerport); //服务端接收客户端发来的连接请求
            if(s == nullptr) exit(0);
            std::cout << "accept success" << std::endl;
            //创建线程
            pthread_t id;
            ThreadData* td = new ThreadData(s, this, peerip, peerport); 
            pthread_create(&id, nullptr, Thread_Run, td); //我们传结构体给Thread_Run函数
            //我们不能join去回收,我们采取将子线程分离(pthread_detach)方式
            //原因:join会阻塞等待,如果有新的客户端想连接(connect)服务端,而server在join阻塞,并没有accept,导致connect失败

            // ssize_t n = recv(s->GetSockfd(), bufferin, sizeof(bufferin)-1, 0); //接收client发送的信息
            // //ssize_t n = (s->GetSockfd(), bufferin, sizeof(bufferin)-1);
            // if(n > 0)
            // {
            //     bufferin[n] = 0;
            //     std::string ret;
            //     ret += peerip;
            //     ret += " ";
            //     ret += std::to_string(peerport);
            //     std::cout << ret << " " << "client say#" << bufferin << std::endl;
            // }
            // else
            // {
            //     break;
            // }
        }
    }

    ~TcpServer()
    {
        delete _listensocket;
    }
private:
    int _port;
    Socket* _listensocket;
};

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值