QT中的TCP

发布于:2025-09-02 ⋅ 阅读:(17) ⋅ 点赞:(0)

QT中的TCP

回显服务器

  1. 创建界⾯. 包含⼀个 QListWidget , ⽤于显⽰收到的数据.

  2. 创建 QTcpServer 并初始化

修改 widget.h, 添加 QTcpServer 指针成员.

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void processConnection();

    QString process(const QString request);
private:
    Ui::Widget *ui;
    QTcpServer *tcpServer;
};
#endif // WIDGET_H

修改 widget.cpp, 实例化 QTcpServer 并进⾏后续初始化操作.

• 设置窗⼝标题

• 实例化 TCP server. (⽗元素设为当前控件, 会在⽗元素销毁时被⼀起销毁).

• 通过信号槽, 处理客⼾端建⽴的新连接.

• 监听端⼝

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //1.修改窗口标题
    this->setWindowTitle("服务器");
    //2.创建TcpServer的实例
    tcpServer=new QTcpServer(this);
    //3.通过信号槽,指定如何处理
    connect(tcpServer,&QTcpServer::newConnection,this,&Widget::processConnection);
    //4.绑定监听端口号
    bool ret=tcpServer->listen(QHostAddress::Any,9090);
    if(!ret)
    {
        QMessageBox::critical(this,"服务器启动失败",tcpServer->errorString());
        exit(1);
    }
}
  1. 继续修改 widget.cpp, 实现处理连接的具体⽅法 processConnection

• 获取到新的连接对应的 socket.

• 通过信号槽, 处理收到请求的情况

• 通过信号槽, 处理断开连接的情况

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

void Widget::processConnection()
{
    QTcpSocket* clientSocket=tcpServer->nextPendingConnection();
    QString log="["+clientSocket->peerAddress().toString()+":"+QString::number(clientSocket->peerPort())+"]客户端上线";
    ui->listWidget->addItem(log);

    connect(clientSocket,&QTcpSocket::readyRead,this,[=](){
        QString request=clientSocket->readAll();
        const QString& response=process(request);
        clientSocket->write(response.toUtf8());
        QString log = QString("[") + clientSocket->peerAddress().toString()
         + ":" + QString::number(clientSocket->peerPort()) + "] 客⼾端下线!";
         ui->listWidget->addItem(log);
         clientSocket->deleteLater();
    });
}

  1. 实现 process ⽅法, 实现根据请求处理响应.

由于我们此处是实现回显服务器. 所以 process ⽅法中并没有包含实质性的内容.

QString Widget::process(const QString request)
{
    return request;
}

💡 “根据请求处理响应” 是服务器开发中的最核⼼的步骤.

⼀个商业服务器程序, 这⾥的逻辑可能是⼏万⾏⼏⼗万⾏代码量级的.

此时, 服务器程序编写完毕.

但是直接运⾏还看不出效果. 还需要搭配客⼾端来使⽤

回显客⼾端

  1. 创建界⾯. 包含⼀个 QLineEdit , QPushButton , QListWidget

• 先使⽤⽔平布局把 QLineEdit 和 QPushButton 放好, 并设置这两个控件的垂直⽅向的sizePolicy 为 Expanding

• 再使⽤垂直布局把 QListWidget 和上⾯的⽔平布局放好.

• 设置垂直布局的 layoutStretch 为 5, 1 (当然这个尺⼨⽐例根据个⼈喜好微调).

  1. 创建 QTcpSocket 并实例化

修改 widget.h, 创建成员.

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
    QTcpSocket*socket;
};
#endif // WIDGET_H

修改 widget.cpp, 对 QTcpSocket 进⾏实例化.

• 设置窗⼝标题

• 实例化 socket 对象 (⽗元素设为当前控件, 会在⽗元素销毁时被⼀起销毁).

• 和服务器建⽴连接.

• 等待并确认连接是否出错

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //1.设置窗口标题
    this->setWindowTitle("客户端");
    //2.创建socket对象实例
    socket=new QTcpSocket(this);
    //3.和服务器建立连接
    socket->connectToHost("127.0.0.1",9090);
    //4.连接信号槽
    connect(socket,&QTcpSocket::readyRead,this,[=](){
        //a)读取响应内容
        QString response=socket->readAll();
        //b)把相应内容显示到界面上
        ui->listWidget->addItem("服务器说:"+response);
    });
    //5.等待连接的结果,确认是否成功
   bool ret=socket->waitForConnected();
   if(!ret)
   {
       QMessageBox::critical(this,"服务器连接错误",socket->errorString());
       exit(1);
   }
}
  1. 修改 widget.cpp, 给按钮增加点击的 slot 函数, 实现发送请求给服务器
void Widget::on_pushButton_clicked()
{
    //1.获取到输入框中的内容
    const QString& text=ui->lineEdit->text();
    //2.发送数据到服务器
    socket->write(text.toUtf8());
    //3.把发的消息显示到界面上
    ui->listWidget->addItem("客户端说:"+text);
    //4.清空输入框的内容
    ui->lineEdit->setText("");
}
  1. 修改 widget.cpp 中的 Widget 构造函数, 通过信号槽, 处理收到的服务器的响应.
connect(socket,&QTcpSocket::readyRead,this,[=](){
        //a)读取响应内容
        QString response=socket->readAll();
        //b)把相应内容显示到界面上
        ui->listWidget->addItem("服务器说:"+response);
    });

的服务器的响应.

connect(socket,&QTcpSocket::readyRead,this,[=](){
        //a)读取响应内容
        QString response=socket->readAll();
        //b)把相应内容显示到界面上
        ui->listWidget->addItem("服务器说:"+response);
    });

网站公告

今日签到

点亮在社区的每一天
去签到