代码拉取完成,页面将自动刷新
//服务端类声明和定义
#pragma once
#include <iostream>
#include <functional>
#include <pthread.h>//提供线程相关函数
#include "Socket.hpp"//提供socket编程接口
using namespace socket_ns;
class TcpServer
{
private:
uint16_t _port;//端口号
std::shared_ptr<Socket> _listensock;//Socket对象,包含监听套接字
bool _isrunning;
std::function<void(std::shared_ptr<Socket>,InetAddr)> _service;//业务处理函数(线程启动函数)
public:
//构造函数
TcpServer(uint16_t port,std::function<void(std::shared_ptr<Socket>,InetAddr)> service)
:_port(port),
_listensock(std::make_shared<TcpSocket>()),//子类对象传递给父类指针
_isrunning(false),
_service(service)
{
_listensock->StartListening(_port);//服务端开始监听
}
//内部类
class ThreadData
{
public:
TcpServer* _self;//TcpServer类指针,用于调用_service
std::shared_ptr<Socket> _readwritesock;//Socket对象,包含读写套接字
InetAddr _clientaddr;//客户端地址信息
public:
//有参构造函数
ThreadData(TcpServer* self, std::shared_ptr<Socket> readwritesock, InetAddr _clientaddr)
:_self(self),
_readwritesock(readwritesock),
_clientaddr(_clientaddr)
{}
};
//服务端循环执行
void Loop()
{
_isrunning=true;
while(_isrunning)
{
//服务端接收客户端连接
InetAddr clientaddr;//保存连接到的客户端地址信息
std::shared_ptr<Socket> readwritesock=_listensock->Accept(&clientaddr);//接收客户端连接,连接成功的话获取到Socket对象,包含读写套接字
if(readwritesock==nullptr)//连接失败,重新连接
{
continue;
}
//由于线程启动函数在类内定义必须设置为静态函数,但是静态函数无法调用非静态成员_service
//因此定义一个内部类,封装TcpServer类对象指针
//将该内部类作为参数传递给线程启动函数,让封装TcpServer类对象指针调用_service
//同时_service函数对象的参数要求是 Socket对象+客户端地址信息
//所以要将Socket对象(包含读写套接字文件描述符)和 连接到的客户端地址信息也封装到内部类中,一并传递给线程启动函数
//多线程执行
pthread_t tid;//线程id
ThreadData* td=new ThreadData(this,readwritesock,clientaddr);
pthread_create(&tid,nullptr,Execute,(void*)td);
}
_isrunning=false;
}
//线程启动函数
static void* Execute(void* args)
{
pthread_detach(pthread_self());//线程分离
ThreadData* td=static_cast<ThreadData*>(args);//强制类型转换
td->_self->_service(td->_readwritesock,td->_clientaddr);//线程调用业务处理函数
td->_readwritesock->CloseSocket();//业务处理完毕,关闭套接字
delete td;//销毁内部类对象
return nullptr;
}
};
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。