QT网络编程之实现TCP客户端和服务端

一.QT5.12实现TCP客户端和服务功能

1.QT中实现TCP通信主要用到了以下类:QTcpServer、QTcpSocket、QHostAddress

2.基本流程:

使用QTcpServer来创建一个TCP服务器,在新的连接建立时,将新建立连接的socket添加到列表中,以便发送数据,同时监听在指定的IP地址和端口上,并在有新的客户端连接上来时进行处理;

使用QTcpSocket来创建一个TCP客户端,连接到服务器并发送数据;

二.代码示例

1.mainwindow.h

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

#include <QMainWindow>

#include    <QTcpServer>

#include    <QLabel>

namespace Ui {

class MainWindow;

}

class MainWindow : public QMainWindow

{

    Q_OBJECT

private:

    QLabel  *LabListen;//状态栏标签

    QLabel  *LabSocketState;//状态栏标签

    QTcpServer *tcpServer; //TCP服务器

    QTcpSocket *tcpSocket;//TCP通讯的Socket

    QString getLocalIP();//获取本机IP地址

protected:

    void    closeEvent(QCloseEvent *event);

public:

    explicit MainWindow(QWidget *parent = 0);

    ~MainWindow();

private slots:

//自定义槽函数

    void    onNewConnection();//QTcpServer的newConnection()信号

    void    onSocketStateChange(QAbstractSocket::SocketState socketState);

    void    onClientConnected(); //Client Socket connected

    void    onClientDisconnected();//Client Socket disconnected

    void    onSocketReadyRead();//读取socket传入的数据

//UI生成的

    void on_actStart_triggered();

    void on_actStop_triggered();

    void on_actClear_triggered();

    void on_btnSend_clicked();

    void on_actHostInfo_triggered();

private:

    Ui::MainWindow *ui;

};

#endif // MAINWINDOW_H

2.mainwindow.cpp

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include    <QtNetwork>

QString MainWindow::getLocalIP()

{//获取本机IPv4地址

    QString hostName=QHostInfo::localHostName();//本地主机名

    QHostInfo   hostInfo=QHostInfo::fromName(hostName);

    QString   localIP="";

    QList<QHostAddress> addList=hostInfo.addresses();//

    if (!addList.isEmpty())

    for (int i=0;i<addList.count();i++)

    {

        QHostAddress aHost=addList.at(i);

        if (QAbstractSocket::IPv4Protocol==aHost.protocol())

        {

            localIP=aHost.toString();

            break;

        }

    }

    return localIP;

}

void MainWindow::closeEvent(QCloseEvent *event)

{//关闭窗口时停止监听

    if (tcpServer->isListening())

        tcpServer->close();;//停止网络监听

    event->accept();

}

MainWindow::MainWindow(QWidget *parent) :

    QMainWindow(parent),

    ui(new Ui::MainWindow)

{

    ui->setupUi(this);

    LabListen=new QLabel("监听状态:");

    LabListen->setMinimumWidth(150);

    ui->statusBar->addWidget(LabListen);

    LabSocketState=new QLabel("Socket状态:");//

    LabSocketState->setMinimumWidth(200);

    ui->statusBar->addWidget(LabSocketState);

    QString localIP=getLocalIP();//本机IP

    this->setWindowTitle(this->windowTitle()+"----本机IP:"+localIP);

    ui->comboIP->addItem(localIP);

    tcpServer=new QTcpServer(this);

    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));

}

MainWindow::~MainWindow()

{

    delete ui;

}

void MainWindow::onNewConnection()

{

//    ui->plainTextEdit->appendPlainText("有新连接");

    tcpSocket = tcpServer->nextPendingConnection(); //创建socket

    connect(tcpSocket, SIGNAL(connected()),

            this, SLOT(onClientConnected()));

    onClientConnected();//

    connect(tcpSocket, SIGNAL(disconnected()),

            this, SLOT(onClientDisconnected()));

    connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),

            this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));

    onSocketStateChange(tcpSocket->state());

    connect(tcpSocket,SIGNAL(readyRead()),

            this,SLOT(onSocketReadyRead()));

}

void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)

{//socket状态变化时

    switch(socketState)

    {

    case QAbstractSocket::UnconnectedState:

        LabSocketState->setText("scoket状态:UnconnectedState");

        break;

    case QAbstractSocket::HostLookupState:

        LabSocketState->setText("scoket状态:HostLookupState");

        break;

    case QAbstractSocket::ConnectingState:

        LabSocketState->setText("scoket状态:ConnectingState");

        break;

    case QAbstractSocket::ConnectedState:

        LabSocketState->setText("scoket状态:ConnectedState");

        break;

    case QAbstractSocket::BoundState:

        LabSocketState->setText("scoket状态:BoundState");

        break;

    case QAbstractSocket::ClosingState:

        LabSocketState->setText("scoket状态:ClosingState");

        break;

    case QAbstractSocket::ListeningState:

        LabSocketState->setText("scoket状态:ListeningState");

    }

}

void MainWindow::onClientConnected()

{//客户端接入时

    ui->plainTextEdit->appendPlainText("**client socket connected");

    ui->plainTextEdit->appendPlainText("**peer address:"+

                                   tcpSocket->peerAddress().toString());

    ui->plainTextEdit->appendPlainText("**peer port:"+

                                   QString::number(tcpSocket->peerPort()));

}

void MainWindow::onClientDisconnected()

{//客户端断开连接时

    ui->plainTextEdit->appendPlainText("**client socket disconnected");

    tcpSocket->deleteLater();

    //    deleteLater();//QObject::deleteLater();

}

void MainWindow::onSocketReadyRead()

{//读取缓冲区行文本

//    QStringList   lines;

    while(tcpSocket->canReadLine())

        ui->plainTextEdit->appendPlainText("[in] "+tcpSocket->readLine());

//        lines.append(clientConnection->readLine());

}

void MainWindow::on_actStart_triggered()

{//开始监听

    QString     IP=ui->comboIP->currentText();//IP地址

    quint16     port=ui->spinPort->value();//端口

    QHostAddress    addr(IP);

    tcpServer->listen(addr,port);//

    ui->plainTextEdit->appendPlainText("**开始监听...");

    ui->plainTextEdit->appendPlainText("**服务器地址:"

                       +tcpServer->serverAddress().toString());

    ui->plainTextEdit->appendPlainText("**服务器端口:"

                       +QString::number(tcpServer->serverPort()));

    ui->actStart->setEnabled(false);

    ui->actStop->setEnabled(true);

    LabListen->setText("监听状态:正在监听");

}

void MainWindow::on_actStop_triggered()

{//停止监听

    if (tcpServer->isListening()) //tcpServer正在监听

    {

        tcpServer->close();//停止监听

        ui->actStart->setEnabled(true);

        ui->actStop->setEnabled(false);

        LabListen->setText("监听状态:已停止监听");

    }

}

void MainWindow::on_actClear_triggered()

{

    ui->plainTextEdit->clear();

}

void MainWindow::on_btnSend_clicked()

{//发送一行字符串,以换行符结束

    QString  msg=ui->editMsg->text();

    ui->plainTextEdit->appendPlainText("[out] "+msg);

    ui->editMsg->clear();

    ui->editMsg->setFocus();

    QByteArray  str=msg.toUtf8();

    str.append('\n');//添加一个换行符

    tcpSocket->write(str);

}

void MainWindow::on_actHostInfo_triggered()

{//获取本机地址

    QString hostName=QHostInfo::localHostName();//本地主机名

    ui->plainTextEdit->appendPlainText("本机主机名:"+hostName+"\n");

    QHostInfo   hostInfo=QHostInfo::fromName(hostName);

    QList<QHostAddress> addList=hostInfo.addresses();//

    if (!addList.isEmpty())

    for (int i=0;i<addList.count();i++)

    {

        QHostAddress aHost=addList.at(i);

        if (QAbstractSocket::IPv4Protocol==aHost.protocol())

        {

            QString IP=aHost.toString();

            ui->plainTextEdit->appendPlainText("本机IP地址:"+aHost.toString());

            if (ui->comboIP->findText(IP)<0)

                ui->comboIP->addItem(IP);

        }

    }

}

三.测试结果

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

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

相关文章

Ubuntu 安装腾讯会议

1.官网下载 进入腾讯会议下载官网下载腾讯会议Linux客户端 选择x86_64格式安装包下载 若不知道自己的系统架构,输入 uname -a 在命令行结果中查看系统架构信息 2.终端命令安装 cd {你的下载路径} sudo dpkg -i TencentMeeting_0300000000_3.19.0.401_x86_64_default.publi…

mysql对索引的选择简述

概述 在业务中经常会优化一些mysql的慢查询&#xff0c;通常都是使用explain去查看分析&#xff0c;检查扫描行数和索引的命中情况&#xff1b; 但是在具体索引的选择上&#xff0c;explain结果中并没有直接展示出来&#xff1b; 此时可以开启mysql的追踪优化器Trace功能&…

如何进行专利布局与专利规避

一、专利布局 WHY 专利布局是指企业或个人在科研或生产过程中&#xff0c;为了保护和利用自身的技术成果&#xff0c;通过综合产业、市场和法律等因素&#xff0c;对专利进行有机结合&#xff0c;构建严密高效的专利保护网&#xff0c;最终形成对企业或个人有利的专利组合。 …

10、Redis分布式系统之数据分区算法

Redis分布式系统之数据分区算法 1、什么是Redis分布式系统 ​ Redis分布式系统&#xff0c;官方称为Redis Cluster, Redis集群&#xff08;这个集群和前面的主从复制集群不同&#xff0c;这个集群可以理解为是多个主从复制集群所组成的集群&#xff09;&#xff0c;其实是Red…

C# RAM Stable Diffusion 提示词反推 Onnx Demo

目录 介绍 效果 模型信息 项目 代码 下载 C# RAM Stable Diffusion 提示词反推 Onnx Demo 介绍 github地址&#xff1a;GitHub - xinyu1205/recognize-anything: Open-source and strong foundation image recognition models. Open-source and strong foundation ima…

基于Redis实现分布式锁、限流操作(基于SpringBoot)的实现

基于Redis实现分布式锁、限流操作——基于SpringBoot实现 本文总结了一种利用Redis实现分布式锁、限流的较优雅的实现方式本文原理介绍较为通俗&#xff0c;希望能帮到有需要的人本文的demo地址&#xff1a;https://gitee.com/rederxu/lock_distributed.git 一、本文基本实现…

《MySQL数据库》day2--连接查询、子查询、union、limit、DML语句

文章目录 1.把查询结果去除重复记录 -》distinct2.连接查询2.1什么是连接查询&#xff1f;2.2连接查询的分类2.3笛卡尔积现象2.4内连接2.4.1内连接之等值连接。2.4.2内连接之非等值连接2.4.3内连接之自连接 2.5外连接2.6三张表&#xff0c;四张表怎么连接&#xff1f; 3.子查询…

SA3D:基于 NeRF 的三维场景分割方法

Paper: Cen J, Zhou Z, Fang J, et al. Segment anything in 3d with nerfs[J]. Advances in Neural Information Processing Systems, 2024, 36. Introduction: https://jumpat.github.io/SA3D/ Code: https://github.com/Jumpat/SegmentAnythingin3D SA3D 是一种用于 NeRF 表…

Java项目:48 ssm008医院门诊挂号系统+jsp(含文档)

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本选题则旨在通过标签分类管理等方式实现 管理员&#xff1b;个人中心、药房管理、护士管理、医生管理、病人信息管理、科室信息管理、挂号管…

【每日一题】2864. 最大二进制奇数-2024.3.13

题目&#xff1a; 2864. 最大二进制奇数 给你一个 二进制 字符串 s &#xff0c;其中至少包含一个 1 。 你必须按某种方式 重新排列 字符串中的位&#xff0c;使得到的二进制数字是可以由该组合生成的 最大二进制奇数 。 以字符串形式&#xff0c;表示并返回可以由给定组合…

基于GIS技术的智慧农业大数据平台解决方案

1.建设背景 国务院促进大数据发展纲要 纲要提出大力推动政府信息系统和公共数据互联开放共享&#xff0c;加快政府信息平台整合&#xff0c;推动数据资源整合&#xff0c;提升治理水平。按照“五个统一”建设“大平台“&#xff0c;融合“大数据”&#xff0c;构建“大系统”落…

Leetcode-热题100-持续更新

时间不够&#xff0c;只能背诵哎&#xff0c;没办法&#xff0c;难题不写&#xff0c;简单题和中等题。 def majorityElement(nums):# 使用字典 count 来记录每个元素的出现次数count {}for num in nums:if num in count:count[num] 1else:count[num] 1length len(nums)#…

喜报!聚铭网络实力入选2024年度扬州市网络安全技术支撑服务机构

近日&#xff0c;中共扬州市委网络安全和信息化委员会办公室正式公布了“2024年度扬州市网络安全技术支撑服务机构”名单&#xff0c;聚铭网络凭借其卓越的技术实力与优质的安服能力&#xff0c;在众多竞争者中脱颖而出&#xff0c;光荣上榜&#xff01; 为了健全扬州市网络安…

zabbix 7.0编译部署教程

zabbix 7.0编译部署教程 2024-03-08 16:50乐维社区 zabbix7.0 alpha版本、beta版本已经陆续发布&#xff0c;Zabbix7.0 LTS版本发布时间也越来越近。据了解&#xff0c;新的版本在性能提升、架构优化等新功能方面有非常亮眼的表现&#xff0c;不少小伙伴对此也已经跃跃欲试。心…

JavaWeb实验 AJAX技术基本应用

实验目的 认识Ajax的作用&#xff1b;能在JSP中应用Ajax与Servlet进行交互。 实验内容 创建一个Java Web应用&#xff0c;综合利用JSP、Ajax和Servlet技术实现中英文互译功能&#xff1a; 在输入框输入英文单词时&#xff0c;在后面即时显示翻译为中文的结果&#xff1b;在输…

下载文件,无法获取header中的Content-Disposition

问题&#xff1a;axios跨域请求时&#xff0c;无法获取header中的Content-Disposition&#xff0c;并且network中已显示Content-Disposition 在使用CORS方式跨域时&#xff0c;浏览器只会返回默认的头部Header 解决&#xff1a; 后端在返回时&#xff0c;需要设置公开的响应…

【项目】C++ 基于多设计模式下的同步异步日志系统

前言 一般而言&#xff0c;业务的服务都是周而复始的运行&#xff0c;当程序出现某些问题时&#xff0c;程序员要能够进行快速的修复&#xff0c;而修复的前提是要能够先定位问题。 因此为了能够更快的定位问题&#xff0c;我们可以在程序运行过程中记录一些日志&#xff0c;通…

选股就用河北源达“财源滚滚”选股软件

在股市投资的道路上&#xff0c;选股无疑是至关重要的一环。然而&#xff0c;面对海量的个股信息和复杂的市场环境&#xff0c;如何科学、准确地选股&#xff0c;成为了投资者必须面对的难题。河北源达信息技术股份有限公司推出的“财源滚滚”选股软件&#xff0c;以其独特的优…

11 vector的实现

注意 实现仿cplus官网的的string类&#xff0c;对部分主要功能实现 实现 文件 #pragma once #include <string> #include <assert.h>namespace myvector {template <class T>class vector{public://iteratortypedef T* iterator;typedef const T* const_…

【AI绘画】AI绘画免费网站推荐

人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;是指一种模拟人类智能的技术。它是通过计算机系统来模拟人的认知、学习和推理能力&#xff0c;以实现类似于人类智能的行为和决策。人工智能技术包含多个方面&#xff0c;包括机器学习、深度学习、自…