通过QT进行服务器和客户端之间的网络通信

news2024/9/20 8:58:07

客户端

client.pro

#-------------------------------------------------
#
# Project created by QtCreator 2024-07-02T14:11:20
#
#-------------------------------------------------

QT       += core gui network   #网络通信

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = client
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += main.cpp\
        widget.cpp

HEADERS  += widget.h

FORMS    += widget.ui

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpSocket>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

    void InitClient();

private slots:
    void on_connect_bt_clicked();
    void on_send_bt_clicked();
    void OnReadData();

private:
    Ui::Widget *ui;

    QTcpSocket *m_pSocket;
};

#endif // WIDGET_H

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.InitClient();
    w.show();

    return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>          //Qt 提供的输出调试信息的工具。
#include <QHostAddress>

Widget::Widget(QWidget *parent) :   //Widget类继承自QWidget
    QWidget(parent),
    ui(new Ui::Widget) //通过ui对象初始化界面布局
{
    ui->setupUi(this);
    m_pSocket = NULL;     //初始化m_pSocket为NULL
}

Widget::~Widget()      //析构函数释放了ui对象。
{
    delete ui;
}

void Widget::InitClient()       //设置界面初始状态,创建串口对象
{
    qDebug() << "Widget::InitClient() enter";
    if (NULL == m_pSocket)
    {
        m_pSocket = new QTcpSocket(this);   //QTcpSocket是Qt提供的用于TCP网络通信的类
        connect(m_pSocket, SIGNAL(readyRead()), this, SLOT(OnReadData()));
        //readyRead()当socket接收到新的数据时发出的信号,SIGNAL()是一个宏,将信号转换为字符串形式。this是信号的发送者。
        //当m_pSocket对象接收到数据时,会触发readyRead()信号,然后调用当前类的OnReadData()槽函数来处理这些接收到的数据
    }
    qDebug() << "Widget::InitClient() exit";
}

void Widget::on_connect_bt_clicked()   //当按钮connect_bt被点击时触发
{
    qDebug() << "Widget::on_connect_bt_clicked() enter";

    QString strIP = ui->ip_edit->text();   //获取用户输入的IP地址
    QString strPort = ui->port_edit->text();
    qDebug() << strIP << " " << strPort;
    if (strIP.length() == 0 || strPort.length() == 0)  //检查用户输入的有效性,如果IP或端口号为空,则输出错误信息并返回
    {
        qDebug() << "input error";
        return;
    }

    if (NULL == m_pSocket)      //检查m_pSocket是否为NULL,如果是则输出错误信息并返回
    {
        qDebug() << "socket error";
        return;
    }

    m_pSocket->connectToHost(QHostAddress("127.0.0.1"), strPort.toShort());
    //使用m_pSocket->connectToHost()连接到指定的主机地址(这里是本地地址 "127.0.0.1")和端口号

    if (m_pSocket->waitForConnected(3000))
    //使用m_pSocket->waitForConnected(3000)等待连接建立,超时时间为3000毫秒(3秒)
    {
        qDebug() << "connect ok";
    }
    else
    {
        qDebug() << "connect error";
    }
    qDebug() << "Widget::on_connect_bt_clicked() exit";
}

void Widget::on_send_bt_clicked()
{
    qDebug() << "Widget::on_send_bt_clicked() enter";
    QString strData = ui->send_edit->text();
    if (strData.length() == 0)
    {
        qDebug() << "input error";
        return;
    }
    if (NULL == m_pSocket)
    {
        qDebug() << "socket error";
        return;
    }
    m_pSocket->write(strData.toStdString().data());    //发送字符串形式的数据到已连接的服务器端
    qDebug() << "Widget::on_send_bt_clicked() exit";
}

void Widget::OnReadData()
{
    QByteArray arr = m_pSocket->readAll();    //读取所有接收到的数据,并将其存储arr中
    qDebug() << arr;
}

widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>692</width>
    <height>468</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>50</x>
     <y>60</y>
     <width>72</width>
     <height>15</height>
    </rect>
   </property>
   <property name="text">
    <string>ip</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="ip_edit">
   <property name="geometry">
    <rect>
     <x>100</x>
     <y>60</y>
     <width>181</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QLabel" name="label_2">
   <property name="geometry">
    <rect>
     <x>40</x>
     <y>100</y>
     <width>72</width>
     <height>15</height>
    </rect>
   </property>
   <property name="text">
    <string>port</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="port_edit">
   <property name="geometry">
    <rect>
     <x>100</x>
     <y>100</y>
     <width>181</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QPushButton" name="connect_bt">
   <property name="geometry">
    <rect>
     <x>350</x>
     <y>90</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>connect</string>
   </property>
  </widget>
  <widget class="QPushButton" name="send_bt">
   <property name="geometry">
    <rect>
     <x>350</x>
     <y>150</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>send</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="send_edit">
   <property name="geometry">
    <rect>
     <x>100</x>
     <y>160</y>
     <width>181</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

服务器

server.pro

#-------------------------------------------------
#
# Project created by QtCreator 2024-07-02T09:20:48
#
#-------------------------------------------------

QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = server
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += main.cpp\
        widget.cpp

HEADERS  += widget.h

FORMS    += widget.ui

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

    void InitServer();

private slots:
    void OnNewConnection();
    void OnReadyData();

    void on_listen_bt_clicked();

private:
    Ui::Widget *ui;
    QTcpServer *m_pServer;
};

#endif // WIDGET_H

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.InitServer();
    w.show();

    return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QHostAddress>
#include <QTcpSocket>

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

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

void Widget::InitServer()
{
    qDebug() << "Widget::InitServer() enter";
    if (NULL == m_pServer)
    {
        m_pServer = new QTcpServer(this);
        connect(m_pServer, SIGNAL(newConnection()), this, SLOT(OnNewConnection()));
    }
    qDebug() << "Widget::InitServer() exit";
}

void Widget::OnNewConnection()
{
    qDebug() << "new connection";
    QTcpSocket *pTmp = m_pServer->nextPendingConnection();  //获取下一个挂起的连接
    if (NULL != pTmp)
    {
        connect(pTmp, SIGNAL(readyRead()), this, SLOT(OnReadyData()));
        //当这个客户端socket有数据可读时,就会调用OnReadyData()函数
    }
}

void Widget::OnReadyData()
{
    qDebug() << "read data";
    QTcpSocket *pTmp = (QTcpSocket *)sender();   //获取信号的发送者
    if (NULL == pTmp)
    {
        qDebug() << "socket error";
        return;
    }
    QByteArray arr = pTmp->readAll();  //读取所有接收到的数据
    //qDebug() << arr;

    QString strData = ui->textEdit->toPlainText();  //将接收到的数据显示在界面中
    strData.append("recv : ");  //追加数据recv :
    strData.append(arr);
    strData.append("\n");
    ui->textEdit->setText(strData);
    pTmp->write(arr);   //将接收到的数据原样发送回客户端
}

void Widget::on_listen_bt_clicked()
{
    qDebug() << "Widget::on_listen_bt_clicked() enter";
    if (NULL == m_pServer)
    {
        return;
    }
    QString strIP = ui->ip_edit->text();
    QString strPort = ui->port_edit->text();
    if (strIP.length() == 0 || strPort.length() == 0)
    {
        qDebug() << "input error";
        return;
    }
    bool bRet = m_pServer->listen(QHostAddress(strIP), strPort.toShort());   //监听指定的IP地址和端口号
    if (bRet == true)
    {
        qDebug() << "server listen ok";
    }
    qDebug() << "Widget::on_listen_bt_clicked() enter";
}

widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>893</width>
    <height>629</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>80</x>
     <y>60</y>
     <width>72</width>
     <height>15</height>
    </rect>
   </property>
   <property name="text">
    <string>ip</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="ip_edit">
   <property name="geometry">
    <rect>
     <x>140</x>
     <y>60</y>
     <width>221</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QLineEdit" name="port_edit">
   <property name="geometry">
    <rect>
     <x>140</x>
     <y>100</y>
     <width>221</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QLabel" name="label_2">
   <property name="geometry">
    <rect>
     <x>80</x>
     <y>100</y>
     <width>72</width>
     <height>15</height>
    </rect>
   </property>
   <property name="text">
    <string>port</string>
   </property>
  </widget>
  <widget class="QPushButton" name="listen_bt">
   <property name="geometry">
    <rect>
     <x>400</x>
     <y>100</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>listen</string>
   </property>
  </widget>
  <widget class="QTextEdit" name="textEdit">
   <property name="geometry">
    <rect>
     <x>60</x>
     <y>190</y>
     <width>761</width>
     <height>401</height>
    </rect>
   </property>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1940720.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

饥荒dst联机服务器搭建基于Ubuntu

目录 一、服务器配置选择 二、项目 1、下载到服务器 2、解压 3、环境 4、启动面板 一、服务器配置选择 首先服务器配置需要2核心4G&#xff0c;4G内存森林加洞穴大概就占75% 之后进行服务器端口的开放&#xff1a; tcp:8082 tcp:8080 UDP:10888 UDP:10998 UDP:10999 共…

套接字编程一(简单的UDP网络程序)

文章目录 一、 理解源IP地址和目的IP地址二、 认识端口号1. 理解 "端口号" 和 "进程ID"2. 理解源端口号和目的端口号 三、 认识协议1. 认识TCP协议2. 认识UDP协议 四、 网络字节序五、 socket编程接口1. socket 常见API2. sockaddr结构&#xff08;1&#…

输入设备应用编程-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

输入设备应用编程 输入类设备编程介绍 什么是输入设备 输入设备&#xff08;input 设备&#xff09;&#xff0c;如鼠标、键盘、触摸屏等&#xff0c;允许用户与系统交互 input 子系统 Linux系统通过input子系统管理多种输入设备 Input子系统提供统一的框架和接口&#xff…

网络编程之LINUX信号

注意发送信号是给进程&#xff0c;不是线程&#xff0c;调用的是KILL函数&#xff0c;SIG是信号种类。pid0是本进程的其他的进程。 可以通过设置ERRNO来查看返回的错误&#xff0c;如下&#xff1a; 当目标进程收到信号后&#xff0c;要对信号进行一些执行操作&#xff1a; 定义…

[每周一更]-(第106期):DNS和SSL协作模式

文章目录 什么是DNS&#xff1f;DNS解析过程DNS解析的底层逻辑 什么是SSL&#xff1f;SSL证书SSL握手过程SSL的底层逻辑 DNS与SSL的协同工作过程 什么是DNS&#xff1f; DNS&#xff08;Domain Name System&#xff0c;域名系统&#xff09;是互联网的重要组成部分&#xff0c…

黑马程序员MySQL基础学习,精细点复习【持续更新】

文章目录 数据库Mysql基础一、数据库1.数据库2.数据库管理系统3.SQL4.Mysql目录结构5.关系型数据库6.SQL基础概念 mysql高级一、数据库备份和还原1.图形化界面备份与还原 二、约束1.分类&#xff1a;2.主键约束3.唯一约束4.非空约束5.默认值约束6.外键约束 三、表关系1.概述2.一…

《Windows API每日一练》13.1 打印基础

在Windows中使用打印机时&#xff0c;在调用一系列与打印相关的GDI绘图函数的背后&#xff0c;实际上启动了一系列模块之间复杂的交互过程&#xff0c;包括 GDI32库模块、打印机设备驱动程序库模块&#xff08;带.DRV后缀的文件&#xff09;、Windows后台打印处理程序&#xff…

5. harbor镜像仓库

harbor镜像仓库 一、镜像仓库1、类型2、构建私有仓库的方案 二、部署harbor仓库(单机版)1、安装docker(略)2、安装docker-compose工具3、安装harbor4、生成harbor需要的证书、密钥(V3版本证书)4.1 创建CA4.2 创建harbor仓库需要的证书 5、编辑harbor配置文件6、启动harbor 三、…

【C++】17.AVL树

一、AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&#xff0c;两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年发明了一种…

Linux实用操作二

文章目录 Linux实用操作二日期、时区&#xff1a;date命令查看日期时间作用&#xff1a;语法&#xff1a;字段解释&#xff1a;操作&#xff1a; 修改Linux系统时区作用&#xff1a;操作&#xff1a; 使用ntp进行时间同步和校准作用&#xff1a;操作&#xff1a; IP地址、主机名…

buuctf web 第五到八题

[ACTF2020 新生赛]Exec 这里属实有点没想到了&#xff0c;以为要弹shell&#xff0c;结果不用 127.0.0.1;ls /PING 127.0.0.1 (127.0.0.1): 56 data bytes bin dev etc flag home lib media mnt opt proc root run sbin srv sys tmp usr var127.0.0.1;tac /f*[GXYCTF2019]Pin…

【数学建模】多波束测线问题(持续更新)

多波束测线问题 问题 1建立模型覆盖宽度海水深度重叠长度重叠率 问题二问题三问题四 问题 1 与测线方向垂直的平面和海底坡面的交线构成一条与水平面夹角为 α \alpha α的斜线&#xff08;如下图&#xff09;&#xff0c;称 α \alpha α为坡度。请建立多波束测深的覆盖宽度及…

世界华人国学泰斗级人物颜廷利:人类史上全球公认最伟大的思想家

世界华人国学泰斗级人物颜廷利:人类史上全球公认最伟大的思想家 颜廷利教授,一位在21世纪东方哲学、科学界具有深远影响力的人物,同时也是当代中国教育界的知名教授、周易起名与易经姓名学的专家,以及现代国学的杰出代表。他在其著作《升命学说》中提出了一系列独到的理论,包括…

Mybatis--分页查询

一、分页查询 分页查询则是在页面上将本来很多的数据分段显示&#xff0c;每页显示用户自定义的行数。可提高用户体验度&#xff0c;同时减少一次性加载&#xff0c;内存溢出风险。 1、真假分页 分页分为&#xff1a;真分页和假分页。 假分页&#xff1a;一次性查询所有数据存入…

笔记小结:卷积神经网络之多输入多输出通道

本文为李沐老师《动手学深度学习》笔记小结&#xff0c;用于个人复习并记录学习历程&#xff0c;适用于初学者 彩色图像具有标准的RGB通道来代表红、绿和蓝&#xff0c;需要三个通道表示&#xff0c;故而只有单输入单输出是不够的。 对于单个输入和单个输出通道的简化例子&…

Yolo-World网络模型结构及原理分析(一)——YOLO检测器

文章目录 概要一、整体架构分析二、详细结构分析YOLO检测器1. Backbone2. Head3.各模块的过程和作用Conv卷积模块C2F模块BottleNeck模块SPPF模块Upsampling模块Concat模块 概要 尽管YOLO&#xff08;You Only Look Once&#xff09;系列的对象检测器在效率和实用性方面表现出色…

【引领未来智造新纪元:量化机器人的革命性应用】

在日新月异的科技浪潮中&#xff0c;量化机器人正以其超凡的智慧与精准的操作&#xff0c;悄然改变着各行各业的生产面貌&#xff0c;成为推动产业升级、提升竞争力的关键力量。今天&#xff0c;让我们一同探索量化机器人在不同领域的广泛应用价值&#xff0c;见证它如何以科技…

CSA笔记4-包/源管理命令以及本地光盘仓库搭建

包/源管理命令 1.rpm是最基础的rmp包的安装命令&#xff0c;需要提前下载相关安装包和依赖包 2.yum/dnf是基于rpm包的自动安装命令&#xff0c;可以自动在仓库中匹配安装软件和依赖包 注意:以上是安装命令&#xff0c;以下是安装源 3.光盘源&#xff1a;是指安装系统时后的…

Air780EP- AT开发-阿里云应用指南

简介 使用AT方式连接阿里云分为一机一密和一型一密两种方式&#xff0c;其中一机一密又包括HTTP认证二次连接和MQTT直连两种方式 关联文档和使用工具&#xff1a; AT固件获取在线加/解密工具阿里云平台 准备工作 Air780EP_全IO开发板一套&#xff0c;包括天线SIM卡&#xff0…

华为云技术精髓笔记(四)-CES基础入门实战

华为云技术精髓笔记(四) CES基础入门实战 一、监控ECS性能 1、 远程登录ECS 步骤一 双击实验桌面的“Xfce终端”打开Terminal&#xff0c;输入以下命令登录云服务器。注意&#xff1a;请使用云服务器的公网IP替换命令中的【EIP】。 LANGen_us.UTF-8 ssh rootEIP说明&#x…