基于QT的tcp server设计

基于Qt,设计了一个tcp server,主要用到:

  • QTcpServer
  • QTcpSocket
  • QThread

UML 类图

TcpServer构造函数:

TcpServer(QString t_server_name,quint32 t_thread_cout,msgHandle t_func=nullptr,QObject *parent = nullptr);
  • t_server_name:服务名字
  • t_thread_cout:支持处理socket的子线程个数
  • t_func:消息处理函数,其类型如下:
    • typedef std::function<void (QByteArray &msg,QTcpSocket* sock)> msgHandle;

TcpServer启动函数:

void startListen(quint16 t_port);
  • t_port:服务端口

tcpserver.h

#ifndef TCPSERVER_H
#define TCPSERVER_H

#include "tcpsocket.h"

#include <QObject>
#include <QTcpServer>
#include <QString>
#include <QThread>
#include <QVector>

struct SocketInfo
{
    quint32 socket_num;
    QThread socket_thread;
};

class TcpServer : public QTcpServer
{
    Q_OBJECT
public:
    explicit TcpServer(QString t_server_name,quint32 t_thread_cout,msgHandle t_func=nullptr,QObject *parent = nullptr);
    ~TcpServer();

    QString getServerName();
    quint16 getServerPort();

public slots:
    void setMsgHandle(msgHandle t_func);
    void startListen(quint16 t_port);
    void stopListen();
    void socketClose(qint32 t_id);

protected:
    void incomingConnection(qintptr socketDescriptor);
    qint32 getMinSocketThread();

private:
    QString m_server_name;
    quint16 m_port;

    quint32 m_thread_count;
    QVector<SocketInfo*> m_thread_vec;
    msgHandle m_func;
};

#endif // TCPSERVER_H

tcpserver.cpp

#include "tcpserver.h"

#include <QByteArray>
#include <QHostAddress>
#include <QNetworkProxyFactory>
#include <QDebug>

TcpServer::TcpServer(QString t_server_name,quint32 t_thread_cout,msgHandle t_func,QObject *parent) :
    QTcpServer(parent),
    m_server_name(t_server_name),
    m_thread_count(t_thread_cout),
    m_func(t_func)
{
    qDebug()<<__FILE__<<":"<<__LINE__<<":"<<"this server is:"<<t_server_name<<endl;
    this->m_port=0; 
    for(quint32 index=0;index<this->m_thread_count;index++)
    {
        SocketInfo *tmp_info=new SocketInfo();
        tmp_info->socket_num=0;
        tmp_info->socket_thread.start();
        this->m_thread_vec.append(tmp_info);
    }
}

TcpServer::~TcpServer()
{
    if(this->isListening())
    {
        this->close();
    }

    int cout=this->m_thread_vec.size();
    for(int index=0;index<cout;index++)
    {
        this->m_thread_vec[index]->socket_thread.terminate();
        this->m_thread_vec[index]->socket_thread.wait();
        delete this->m_thread_vec[index];
        this->m_thread_vec[index]=nullptr;
    }
}

QString TcpServer::getServerName()
{
    return this->m_server_name;
}

quint16 TcpServer::getServerPort()
{
    return this->m_port;
}

void TcpServer::setMsgHandle(msgHandle t_func)
{
    this->m_func=t_func;
}

void TcpServer::startListen(quint16 t_port)
{
    if(this->isListening())
    {
        this->close();
    }

    if(this->listen(QHostAddress::Any,t_port))
    {
        qDebug()<<__FILE__<<":"<<__LINE__<<":"<<"listen successful:"<<t_port<<endl;
        this->m_port=t_port;
    }
    else
    {
        qDebug()<<__FILE__<<":"<<__LINE__<<":"<<"listen failed:"<<t_port<<endl;
    }
}

void TcpServer::stopListen()
{
    qDebug()<<__FILE__<<":"<<__LINE__<<":"<<"stop listen: "<<this->m_port<<endl;
    if(this->isListening())
    {
        this->close();
    }
}

void TcpServer::incomingConnection(qintptr socketDescriptor)
{
    qDebug()<<__FILE__<<":"<<__LINE__<<":"<<"new connection: "<<socketDescriptor<<endl;
    qint32 cut_id=this->getMinSocketThread();

    TcpSocket *tmp_soc=new TcpSocket(cut_id,socketDescriptor,this->m_func);
    connect(tmp_soc,SIGNAL(socketClose(qint32)),this,SLOT(socketClose(qint32)));
    tmp_soc->moveToThread(&(this->m_thread_vec[cut_id]->socket_thread));
    this->m_thread_vec[cut_id]->socket_num++;
}

void TcpServer::socketClose(qint32 t_id)
{

    this->m_thread_vec[t_id]->socket_num--;
}

qint32 TcpServer::getMinSocketThread()
{
    qint32 tmp_id=0;
    qint32 th_cout=this->m_thread_vec.size();
    for(qint32 index=0;index<th_cout;index++)
    {
        if(this->m_thread_vec[index]->socket_num<this->m_thread_vec[tmp_id]->socket_num)
        {
            tmp_id=index;
        }
    }
    return tmp_id;
}

tcpsocket.h

#ifndef TCPSOCKET_H
#define TCPSOCKET_H

#include <QObject>
#include <QTcpSocket>
#include <QByteArray>
#include <QTimer>

#include <iostream>
#include <functional>

typedef std::function<void (QByteArray &msg,QTcpSocket* sock)> msgHandle;

class TcpSocket : public QTcpSocket
{
    Q_OBJECT
public:
    explicit TcpSocket(qint32 id,qintptr socketDescriptor,msgHandle t_msg_handle=nullptr,QObject *parent = nullptr);
    ~TcpSocket();

signals:
    void socketClose(qint32);

public slots:
    void msgTimeout();
    void readMessage();
    void socketErr(QAbstractSocket::SocketError tError);
    void socketdisconnect();

private:
    qint32 m_id;
    msgHandle m_msg_handle;

    QTimer *m_msg_timeout;
};

#endif // TCPSOCKET_H

tcpsocket.cpp

#include "tcpsocket.h"

#include <QByteArray>
#include <QHostAddress>
#include <QDebug>

static const qint32 TIMEOUT_VALUE=30000;

TcpSocket::TcpSocket(qint32 id,qintptr socketDescriptor,msgHandle t_msg_handle,QObject *parent) :
    QTcpSocket(parent),
    m_id(id),
    m_msg_handle(t_msg_handle)
{
    m_msg_timeout =new QTimer(this);
    connect(this->m_msg_timeout,SIGNAL(timeout()),this,SLOT(msgTimeout()));
    this->setSocketDescriptor(socketDescriptor);
    connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketErr(QAbstractSocket::SocketError)));
    connect(this,SIGNAL(disconnected()),this,SLOT(socketdisconnect()));
    connect(this, SIGNAL(readyRead()), this, SLOT(readMessage()));

    this->m_msg_timeout->start(TIMEOUT_VALUE);
}

TcpSocket::~TcpSocket()
{
    this->disconnectFromHost();
}

void TcpSocket::msgTimeout()
{
    qDebug()<<__FILE__<<":"<<__LINE__<<":"<<"socket connect free timeout"<<endl;
    this->disconnectFromHost();
}

void TcpSocket::readMessage()
{
    this->m_msg_timeout->stop();
    QByteArray t_message=this->readAll();
    if(this->m_msg_handle!=nullptr)
    {
        m_msg_handle(t_message,this);
    }

    this->m_msg_timeout->start(TIMEOUT_VALUE);
}

void TcpSocket::socketErr(QAbstractSocket::SocketError tError)
{
    qDebug()<<__FILE__<<":"<<__LINE__<<":"<<"id: "<<this->socketDescriptor()<<"socket error: "<<this->errorString()<<endl;
    switch (tError)
    {
    case QAbstractSocket::RemoteHostClosedError:
        this->disconnectFromHost();
        break;
    default:
        this->disconnectFromHost();
        break;
    }
}

void TcpSocket::socketdisconnect()
{
    emit socketClose(this->m_id);
    this->deleteLater();
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: qt 212server是一个用于创建分布式、高可靠和可扩展网络应用程序的服务器框架。它基于Qt开发工具包,提供了丰富的功能和工具,可以帮助开发人员轻松地构建和管理服务器端应用程序。 qt 212server具有以下特点和功能: 1. 分布式架构:qt 212server支持分布式架构,可以将服务器拆分为多个节点,提高系统的性能和可扩展性。每个节点可以独立运行并处理特定的任务,通过通信机制进行交互和协作。 2. 高可靠性:qt 212server提供了高可靠性的解决方案,在服务器发生故障或部分节点失效时能够自动进行故障转移和恢复。它使用心跳检测等机制来监控服务器的状态,并采取相应措施保证系统的可用性。 3. 多协议支持:qt 212server支持多种网络协议,包括TCP/IP、HTTP、WebSocket等,可以根据具体需求选择适合的协议进行通信。它还提供了丰富的网络编程接口和工具,方便开发人员进行网络通信的管理和处理。 4. 安全性:qt 212server考虑了网络应用程序的安全性要求,在设计和实现上采用了一系列的安全机制,如数据加密、身份验证、访问控制等,保护服务器和应用程序免受恶意攻击和非法访问。 5. 可扩展性:qt 212server支持动态扩展和灵活配置,可以根据业务需求和负载变化进行动态调整和水平扩展。开发人员可以根据具体情况进行服务器的优化和配置,以提高系统的性能和可用性。 总之,qt 212server是一个功能强大且易于使用的服务器框架,适用于各种规模的网络应用程序的开发和部署。它提供了丰富的功能和工具,支持分布式架构、高可靠性、多协议通信、安全性和可扩展性等特性,帮助开发人员构建稳定、高效和安全的网络应用程序。 ### 回答2: Qt 212server是一个基于Qt框架开发的服务器软件。Qt是一种跨平台的应用程序开发框架,可以用于开发各种类型的应用程序,包括图形界面程序、服务器程序等。 Qt 212server通过提供一套丰富的库和工具,使开发者能够更加快速、方便地开发服务器软件。它提供了各种网络功能,支持常见的网络通信协议,例如TCP/IP、UDP等。开发者可以使用Qt 212server来实现客户端与服务器之间的通信,搭建网络服务。 Qt 212server还提供了多线程支持,可以同时处理多个客户端请求,提高服务器的并发性能。它还支持异步编程,能够以非阻塞的方式处理网络请求,避免了服务器在等待I/O操作时的资源浪费。 Qt 212server还具有良好的可扩展性和可定制性。开发者可以根据自己的需求对服务器进行定制,添加自己的业务逻辑,实现特定的功能。同时,Qt框架本身也提供了丰富的插件和扩展,可以方便地集成第三方库和组件。 总之,Qt 212server是一款功能强大、易于使用和定制的服务器软件。它所提供的网络功能和多线程支持使其成为开发高性能、高并发服务器的理想选择。同时,Qt框架的特性还能够大大简化服务器的开发过程,提高开发效率。 ### 回答3: QT 212Server是一款用于嵌入式系统的服务器软件,由QT公司开发。它提供了丰富的功能和灵活的性能,适用于各种嵌入式设备和应用领域。 QT 212Server具有高度稳定性和可靠性,可以在长时间运行的情况下保持高效工作。它采用模块化设计,可以根据需求自定义功能和配置,从而满足不同设备和应用的要求。 该服务器软件支持多种通信协议,包括TCP/IP、HTTP、FTP等,可以实现设备之间的无缝通信和数据传输。它还可以实现云端和本地数据的同步和共享,方便用户随时查看和管理数据。 QT 212Server还提供了强大的安全性措施,可以保护设备和数据的安全。它支持用户身份验证和权限控制功能,用户可以根据需求设置登录和访问权限,确保只有授权用户可以进行操作。 此外,QT 212Server还具有友好的界面和简单易用的操作方式,使用户可以快速上手并进行有效的管理和配置。它提供了丰富的工具和功能,如日志记录、远程维护、数据分析等,方便用户进行设备监控、故障排除和性能优化。 综上所述,QT 212Server是一款功能强大、稳定可靠的嵌入式服务器软件。它提供了灵活的功能和高效的性能,可以满足各种嵌入式设备和应用的需求,并提供安全可靠的数据传输和管理功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值