Qt多线程服务器-回声(将客户端发来的数据返回给客户端)

关键点是要重写QTcpServer中的一个虚函数void incomingConnection(qintptr socketDescriptor)当有新连接时会自动调用此函数。参数qintptr socketDescriptor为原始套接字,相当于连接后与客户端通讯的套接字。
下面以客户端带ui,服务器端未设计ui但有ui文件widget来简要说明。
服务器端相应文件
myserver.h及myserver.cpp文件

#ifndef MYSERVER_H
#define MYSERVER_H

#include <QTcpServer>

class MyThread;

class MyServer : public QTcpServer
{
    Q_OBJECT
public:
    MyServer(QWidget *parent = nullptr);

    virtual void incomingConnection(qintptr socketDescriptor);
signals:
};
#endif // MYSERVER_H
#include "myserver.h"
#include "mythread.h"
#include <QDebug>

MyServer::MyServer(QWidget *parent)
{

}

void MyServer::incomingConnection(qintptr socketDescriptor)//一旦有连接就会调用这个
{
    MyThread *thread = new MyThread(nullptr, socketDescriptor);//加入到线程队列
    thread->start();//去调用run方法
    connect(thread, &MyThread::finished,thread,&MyThread::deleteLater);//线程终止
}

mysocket.h及mysocket.cpp

#ifndef MYSOCKET_H
#define MYSOCKET_H

#include <QTcpSocket>
#include <QFile>


class MySocket : public QTcpSocket
{
    Q_OBJECT
public:
    MySocket(QWidget *parent, qintptr socket);
    //处理新来的链接
public slots:
    void on_connected();
public:

signals:
};

#endif // MYSOCKET_H

#include "mysocket.h"
#include <QDebug>
#include<QMutex>

MySocket::MySocket(QWidget *parent, qintptr socket) : QTcpSocket(nullptr)
{
    this->setSocketDescriptor(socket);

    connect(this, &MySocket::disconnected, [=]{
        this->disconnectFromHost();
        this->close();
        qDebug() << "disconnected";//通信套接字关闭
    });
}

void MySocket::on_connected()
{
    //读到数据的操作
   QByteArray array = this->readAll();
   qDebug()<<array.data();
   this->write(array);
}

mythread.h及myhread.cpp

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>
#include <QWidget>

class MyTcpSocket;

class MyThread : public QThread
{
    Q_OBJECT
public:
    MyThread(QWidget *parent, qintptr socket);

private:
    qintptr p;
    MyTcpSocket *socket;
    virtual void run();

signals:
public slots:
    void deal_quit();

};

#endif // MYTHREAD_H

#include "mythread.h"
#include "mysocket.h"
#include <QDebug>

MyThread::MyThread(QWidget *parent, qintptr socket) : QThread(parent)
{
    this->p = socket;
}

void MyThread::run()
{
    MySocket *socket = new MySocket(nullptr, this->p);
    connect(socket,&MySocket::readyRead,socket,&MySocket::on_connected);
    //connect(socket, &MySocket::disconnected, this, &MyThread::quit, Qt::DirectConnection);
    connect(socket, &MySocket::disconnected, this, &MyThread::deal_quit, Qt::DirectConnection);//可以直接使用上面一行,要想显示具体信选择此行
    this->exec();//进入线程事件循环
}

void MyThread::deal_quit(){
    qDebug()<<this->currentThreadId()<<"quit";
    this->quit();
}

客户端相应文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QTcpSocket>
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void deal_();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    QTcpSocket *so;
};

#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QHostAddress>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    so = new QTcpSocket(this);
    so->connectToHost(QHostAddress("127.0.0.1"),8888);

    connect(so,&QTcpSocket::connected,this,[=](){
         so->write(QString("nihao server").toUtf8());
    });
    connect(so,&QTcpSocket::readyRead,this,&MainWindow::deal_);
}


void MainWindow::deal_(){
    QByteArray array = so->readAll();
    qDebug()<<array.data();

}
MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    QString f = QString::fromLocal8Bit("%1#%2").arg(ui->lineEdit_1->text()).arg(ui->lineEdit_2->text());
    so->write(f.toUtf8());
}

执行结果展示
在这里插入图片描述
控制台输出(client_deal为服务器)
在这里插入图片描述
在这里插入图片描述
参考博客:https://blog.csdn.net/wayrboy/article/details/83108755
附程序包:https://download.csdn.net/download/A315776/12471545

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值