当前位置: 首页 > article >正文

搭建基于QT的TCP服务器与客户端

1、实现功能

1、服务器和客户端能够建立连接

2、服务器可以给客户端发送信息

3、客户端可以给服务器发送信息

2、server

2-1、widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
public slots:
    void readData();
private slots:
    void on_send_btn_clicked();

private:
    Ui::Widget *ui;
    QTcpServer *server;
    QTcpSocket *client;
};
#endif // WIDGET_H

2-2、widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //设置一下窗口标题
    this->setWindowTitle("server");
    //实例化服务器对象
    this->server = new QTcpServer(this);
    //创建监听队列并邦定ip和port
    //本地主机ip,端口号为1024~49151
    this->server->listen(QHostAddress("192.168.12.47"), 9999);
    //等待客户端连接,做信号与槽函数关联
    connect(this->server, &QTcpServer::newConnection, this, [=]()
    {
        this->client = this->server->nextPendingConnection();
        //得到了客户端,就可以进行通信
        connect(this->client, &QTcpSocket::readyRead, this, &Widget::readData);
    });
}

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

//从客户端读数据
void Widget::readData()
{
    //从客户端中读数据
    QByteArray data = this->client->readAll();
    //读到的数据添加到recv_edit中
    this->ui->recv_edit->append(data);
}

//给客户端写数据
void Widget::on_send_btn_clicked()
{
    //获取到需要发送给客户端的数据
    QString data = this->ui->send_edit->text();
    //发送给客户端
    this->client->write(data.toUtf8());
    //清空输入框
    this->ui->send_edit->clear();
}

2-3、widget.ui

 

3、client

3-1、widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_connect_btn_clicked();
    void on_send_btn_clicked();

public slots:
    void readData();
private:
    Ui::Widget *ui;
    QTcpSocket *client;
    int flag;
    int src_size;
    QByteArray src_data;
};
#endif // WIDGET_H

3-2、widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QHostAddress>
#include <QMessageBox>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("client");

    this->flag = 0;
    this->src_size = 0;
    this->src_data.clear();

    //实例化客户端套接字对象
    this->client = new QTcpSocket(this);
    //成功连接与否,信号与槽的关联
    connect(this->client, &QTcpSocket::connected, this, [=]()
    {
        QMessageBox::information(this, "提示", "成功建立连接");
    });
    //进行通信,读是被动的,需要做信号与槽关联
    connect(this->client, &QTcpSocket::readyRead, this, &Widget::readData);
}

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

//连接服务器
void Widget::on_connect_btn_clicked()
{
    //获取ip和port
    QString ip = this->ui->ip_edit->text();
    uint port = this->ui->port_edit->text().toUInt();
    //连接服务器
    this->client->connectToHost(QHostAddress(ip), port);
}

//从客户端读数据
void Widget::readData()
{
//    //从客户端中读数据
//    QByteArray data = this->client->readAll();
//    //读到的数据添加到recv_edit中
//    this->ui->recv_edit->append(data);
    char buf[256] = {0};
    if(this->flag == 0)
    {
        this->client->read(buf, 256);  //FILE_SIZE#文件大小
        QStringList info = QString(buf).split("#");
        if(info.front() == "FILE_SIZE")
        {
             //获取到图片文件的大小
             this->src_size = info.back().toInt();
             this->flag = 1;
        }
    }
    else if(this->flag == 1) //开始接收真正的图像数据
    {
         QByteArray data = this->client->readAll();
         //保存下来
         this->src_data.append(data);
         if(this->src_data.size() == this->src_size)
         {
              //下载成功
              QPixmap pix;
              pix.loadFromData(this->src_data);
              this->ui->label->setPixmap(pix.scaled(this->ui->label->size()));
              this->flag = 0;
              this->src_size = 0;
              this->src_data.clear();
         }
    }
}

//给客户端写数据
void Widget::on_send_btn_clicked()
{
    //获取到需要发送给客户端的数据
    QString data = this->ui->send_edit->text();
    //发送给客户端
    this->client->write(data.toUtf8());
    //清空输入框
    this->ui->send_edit->clear();
}

3-3、widget.ui


http://www.kler.cn/a/291574.html

相关文章:

  • SQL,生成指定时间间隔内的事件次序号
  • MacroSan 2500_24A配置
  • 常耀斌:深度学习和大模型原理与实战(深度好文)
  • webview和H5来实现的android短视频(短剧)音视频播放依赖控件
  • MobaXterm 连接不上VMware 的Ubuntu 虚拟机
  • lpips使用笔记
  • 国际标准图像分辨率测试ISO12233 - 2017中文翻译
  • MyBatis:解决数据库字段和Java对象字段不匹配问题及占位符问题
  • 「Python程序设计」模块式编程:函数
  • 基于 SpringBoot 冬奥会科普平台
  • 【Java】实体类Javabean的运用案例
  • 社区电商系统源码之卷轴模式:商业模式分析
  • BUUCTF—[网鼎杯 2020 朱雀组]phpweb
  • Laravel 中间件与事件应用教程
  • CSS解析:盒模型
  • Selenium 调用 JavaScript 操作带有 readonly 属性 的日期控件
  • erlang学习:用ETS和DETS存储数据
  • Ascend C算子性能优化实用技巧02——内存优化
  • 获取Word、PPT、Excel、PDF文件页数及加密校验
  • 145. 利用 Redis Bitmap实践: 用户签到统计
  • Android TextView设置跑马灯失效
  • ACL实验配置学习笔记
  • 【网络安全 | 渗透工具】Cencys+Shodan使用教程
  • 科研绘图系列:R语言差异基因四分图(Quad plot)
  • 【轻松学EntityFramework Core】--数据迁移
  • 【高阶数据结构】B树、B+树、B*树