Qt 实现简单的tcp网络通信

2023-05-16

文章目录

    • 成品效果图:
    • 代码:
      • 工具头文件tool.h
      • UI文件代码 ui_widget.h:
      • 窗口头文件 widget.h:
      • 窗口源文件widget.cpp:
    • 相关代码说明:
      • Qt获取本机ip:
      • Qt 打开,监视服务端端口:
      • Qt 客户端连接服务端:
      • Qt 服务端被连接后接收显示并接收消息:
      • Qt 发送消息:
    • 最后:
    • 成品:

背景:
最近计网要结课了,匆忙之间有个计网实验还没做。
上网这里查查那里查查,随便搞搞
然后在 这篇文章里找到了能够实现的代码
自己想着把它图形化一下,最后在超级棒棒糖的帮助下实现了。

成品效果图:

在这里插入图片描述

代码:

工具头文件tool.h

该头文件用于添加一些要用到的库,直接引用这个库,比较方便美观

#ifndef TOOL_H
#define TOOL_H
#include<winsock2.h>
#include<QDateTime>

#include <ws2tcpip.h>
#include <stdio.h>
#include <QDebug>

#include <QNetworkInterface>
#include <QNetworkInterface>
#include <QDebug>
#include <QtNetwork>


#endif // TOOL_H

UI文件代码 ui_widget.h:

/********************************************************************************
** Form generated from reading UI file 'widget.ui'
**
** Created by: Qt User Interface Compiler version 5.12.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFrame>
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QTextBrowser>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QToolButton>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QLabel *label;
    QTextBrowser *SeverState;
    QFrame *line;
    QToolButton *send;
    QFrame *line_2;
    QTextBrowser *talk;
    QWidget *horizontalLayoutWidget;
    QHBoxLayout *horizontalLayout;
    QLabel *label_2;
    QLineEdit *posline;
    QToolButton *Open;
    QGroupBox *groupBox;
    QLabel *label_3;
    QLineEdit *TheIp;
    QLabel *label_4;
    QLineEdit *TheHost;
    QToolButton *connectIp;
    QTextBrowser *Showip;
    QLabel *label_5;
    QTextBrowser *connectState;
    QTextEdit *TextCin;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName(QString::fromUtf8("Widget"));
        Widget->resize(1106, 823);
        label = new QLabel(Widget);
        label->setObjectName(QString::fromUtf8("label"));
        label->setGeometry(QRect(20, 180, 131, 41));
        label->setStyleSheet(QString::fromUtf8("font:20px"));
        SeverState = new QTextBrowser(Widget);
        SeverState->setObjectName(QString::fromUtf8("SeverState"));
        SeverState->setGeometry(QRect(10, 240, 271, 131));
        line = new QFrame(Widget);
        line->setObjectName(QString::fromUtf8("line"));
        line->setGeometry(QRect(350, 610, 761, 21));
        line->setFrameShape(QFrame::HLine);
        line->setFrameShadow(QFrame::Sunken);
        send = new QToolButton(Widget);
        send->setObjectName(QString::fromUtf8("send"));
        send->setGeometry(QRect(940, 720, 151, 71));
        send->setStyleSheet(QString::fromUtf8("font:30px"));
        line_2 = new QFrame(Widget);
        line_2->setObjectName(QString::fromUtf8("line_2"));
        line_2->setGeometry(QRect(340, 0, 31, 821));
        line_2->setFrameShape(QFrame::VLine);
        line_2->setFrameShadow(QFrame::Sunken);
        talk = new QTextBrowser(Widget);
        talk->setObjectName(QString::fromUtf8("talk"));
        talk->setGeometry(QRect(370, 20, 721, 571));
        horizontalLayoutWidget = new QWidget(Widget);
        horizontalLayoutWidget->setObjectName(QString::fromUtf8("horizontalLayoutWidget"));
        horizontalLayoutWidget->setGeometry(QRect(0, 80, 351, 71));
        horizontalLayout = new QHBoxLayout(horizontalLayoutWidget);
        horizontalLayout->setSpacing(6);
        horizontalLayout->setContentsMargins(11, 11, 11, 11);
        horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
        horizontalLayout->setContentsMargins(0, 0, 0, 0);
        label_2 = new QLabel(horizontalLayoutWidget);
        label_2->setObjectName(QString::fromUtf8("label_2"));
        label_2->setStyleSheet(QString::fromUtf8("font:25px;"));

        horizontalLayout->addWidget(label_2);

        posline = new QLineEdit(horizontalLayoutWidget);
        posline->setObjectName(QString::fromUtf8("posline"));

        horizontalLayout->addWidget(posline);

        Open = new QToolButton(horizontalLayoutWidget);
        Open->setObjectName(QString::fromUtf8("Open"));
        Open->setStyleSheet(QString::fromUtf8("font:30px"));

        horizontalLayout->addWidget(Open);

        groupBox = new QGroupBox(Widget);
        groupBox->setObjectName(QString::fromUtf8("groupBox"));
        groupBox->setGeometry(QRect(10, 390, 301, 261));
        groupBox->setStyleSheet(QString::fromUtf8("font:20px"));
        label_3 = new QLabel(groupBox);
        label_3->setObjectName(QString::fromUtf8("label_3"));
        label_3->setGeometry(QRect(10, 30, 221, 31));
        TheIp = new QLineEdit(groupBox);
        TheIp->setObjectName(QString::fromUtf8("TheIp"));
        TheIp->setGeometry(QRect(10, 60, 281, 31));
        label_4 = new QLabel(groupBox);
        label_4->setObjectName(QString::fromUtf8("label_4"));
        label_4->setGeometry(QRect(10, 110, 151, 41));
        TheHost = new QLineEdit(groupBox);
        TheHost->setObjectName(QString::fromUtf8("TheHost"));
        TheHost->setGeometry(QRect(10, 160, 281, 31));
        connectIp = new QToolButton(groupBox);
        connectIp->setObjectName(QString::fromUtf8("connectIp"));
        connectIp->setGeometry(QRect(20, 210, 161, 41));
        Showip = new QTextBrowser(Widget);
        Showip->setObjectName(QString::fromUtf8("Showip"));
        Showip->setGeometry(QRect(115, 10, 231, 41));
        label_5 = new QLabel(Widget);
        label_5->setObjectName(QString::fromUtf8("label_5"));
        label_5->setGeometry(QRect(10, 10, 101, 41));
        label_5->setStyleSheet(QString::fromUtf8("font:25px"));
        connectState = new QTextBrowser(Widget);
        connectState->setObjectName(QString::fromUtf8("connectState"));
        connectState->setGeometry(QRect(30, 660, 256, 151));
        TextCin = new QTextEdit(Widget);
        TextCin->setObjectName(QString::fromUtf8("TextCin"));
        TextCin->setGeometry(QRect(360, 620, 561, 191));

        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QApplication::translate("Widget", "\345\260\217chat", nullptr));
        label->setText(QApplication::translate("Widget", "\346\234\215\345\212\241\347\253\257\347\212\266\346\200\201\357\274\232", nullptr));
        send->setText(QApplication::translate("Widget", "\345\217\221\351\200\201", nullptr));
        label_2->setText(QApplication::translate("Widget", "\346\234\215\345\212\241\345\231\250\345\274\200\346\224\276\347\253\257\345\217\243", nullptr));
        Open->setText(QApplication::translate("Widget", "\346\211\223\345\274\200", nullptr));
        groupBox->setTitle(QApplication::translate("Widget", "\350\277\236\346\216\245\345\214\272", nullptr));
        label_3->setText(QApplication::translate("Widget", "\345\257\271\346\226\271\346\234\215\345\212\241\345\231\250ip\357\274\232", nullptr));
        label_4->setText(QApplication::translate("Widget", "\345\257\271\346\226\271\346\234\215\345\212\241\347\253\257\345\217\243\357\274\232", nullptr));
        connectIp->setText(QApplication::translate("Widget", "\350\277\236\346\216\245", nullptr));
        label_5->setText(QApplication::translate("Widget", "\346\234\254\346\234\272ip:", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

窗口头文件 widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "tool.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

    ~Widget();

private:
    Ui::Widget *ui;
    QTcpServer server;     //TCP控制本地服务器
    quint16 host;           //开放端口
    QTcpSocket *socket = new QTcpSocket(this);     //连接其他的Socket
    QTcpSocket *so = new QTcpSocket(this);         //被连接的Socket
    QString AimIp;
    quint16 AimPort;


private slots:
    void openHost(); //开放某个端口
    void toConnect(); //连接端口
    void toSend();      //发送信息
};

#endif // WIDGET_H

窗口源文件widget.cpp:

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

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    QList<QHostAddress> list = QNetworkInterface::allAddresses();
    for(int nIter=0; nIter<list.count(); nIter++)
    {
        if(!list[nIter].isLoopback())
        {
            if(list[nIter].protocol() == QAbstractSocket::IPv4Protocol )
            {
                qDebug() << list[nIter].toString();
                ui->Showip->append(list[nIter].toString());
            }
        }
    }

    connect(ui->Open, &QToolButton::clicked,this, &Widget::openHost);//打开端口
    connect(ui->connectIp, &QToolButton::clicked,this,&Widget::toConnect);//连接
    connect(ui->send, &QToolButton::clicked, this,&Widget::toSend);
    //被连接
    connect(&server, &QTcpServer::newConnection, this, [=]() {
        so = server.nextPendingConnection();
        QString ip = so->peerAddress().toString();
        quint16 port = so->peerPort();
        qDebug() << "New connection from " << ip << ":" << port;

        QString m = "<font color='blue'>有新的连接来自"+ip+":"+QString::number(port)+"</font>";
        ui->SeverState->append(m);
        //被连接后接收信息:
        connect(so, &QTcpSocket::readyRead, this, [=]() {
            QDateTime currentDateTime = QDateTime::currentDateTime();
            QString ip = so->peerAddress().toString();
            QByteArray data = so->readAll();
            qDebug() << "Received data:" << data;
            QString mag1 = QString::fromUtf8(data);
            qDebug()<<currentDateTime;
            QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
            QString mag = "<font color='blue'>"+strDateTime+"收到来自"+ip+"的消息:"+mag1+"</font>";
            ui->talk->append(mag);
        });
    });


    //连接成功:
    connect(socket, &QTcpSocket::connected, this, [=]() {
        qDebug() << "Connected to server.";

        // 发送信息给服务端
        QByteArray message = "连接你了";
        socket->write(message);
    });

    // 接收服务端发送的信息
    connect(socket, &QTcpSocket::readyRead, this, [=]() {
        QDateTime currentDateTime = QDateTime::currentDateTime();
        QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
        QString ip = socket->peerAddress().toString();
        QByteArray data = socket->readAll();
        QString message = QString::fromUtf8(data);
        qDebug() << "Received message from server:" << message;
        QString mag = "<font color='blue'>"+strDateTime+"收到来自"+ip+"的消息:"+message+"</font>";
        ui->talk->append(mag);
    });


}



void Widget::openHost(){
    int temp = this->ui->posline->text().toInt();
    this->host = static_cast<quint16>(temp);
    qDebug()<<"端口:"<<this->host<<endl;

    server.close();
    if(!this->server.listen(QHostAddress::Any, this->host)){
        qDebug()<<"端口开放失败"<<endl;
        this->ui->SeverState->append("<font color='red'>端口开放失败</font>");
    }
    else{
        this->ui->SeverState->append(this->ui->posline->text()+"端口已开放");
    }

}

void Widget::toConnect(){

    AimIp = ui->TheIp->text();
    int h = ui->TheHost->text().toInt();
    AimPort = static_cast<quint16>(h);
    socket->connectToHost(AimIp,AimPort);
    if (socket->waitForConnected()) {
        // 连接成功
        qDebug() << "Connected to server!";
        QString mag = "连接"+this->AimIp+"的端口"+ui->TheHost->text()+"成功";
        ui->connectState->append(mag);



    } else {
        // 连接失败
        QString mag = "连接"+this->AimIp+"的端口"+ui->TheHost->text()+"失败";
        qDebug() << "Failed to connect to server: " << socket->errorString();
        mag = "<font color='red'>"+mag+"</font>";
        ui->connectState->append(mag);
    }
}

void Widget::toSend(){
    QString mag = this->ui->TextCin->toPlainText();
    so->write(mag.toUtf8());
    so->flush();
    so->waitForBytesWritten();
    socket->write(mag.toUtf8());
    socket->flush();
    socket->waitForBytesWritten();
    QDateTime currentDateTime = QDateTime::currentDateTime();
    QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
    QString smag = strDateTime+"向"+this->AimIp+"发送消息:"+mag;
    ui->talk->append(smag);
    ui->TextCin->clear();
}


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

相关代码说明:

Qt获取本机ip:

	QList<QHostAddress> list = QNetworkInterface::allAddresses();
    for(int nIter=0; nIter<list.count(); nIter++)
    {
        if(!list[nIter].isLoopback())
        {
            if(list[nIter].protocol() == QAbstractSocket::IPv4Protocol )
            {
                qDebug() << list[nIter].toString();//输出端口信息
            }
        }
    }
    

Qt 打开,监视服务端端口:

QTcpServer server;
quint16 host = 8080;
server.listen(QHostAddress::Any, host);

这里的listen()函数则是打开端口并监视,不过要注意,一个server只能打开监视一个端口。

Qt 客户端连接服务端:

这里的客户端其实也就是你自己的主机,你自己的主机也可以充当服务端捏。

	QString AimIp = "127.0.0.1"
    quint16 AimPort = 8080;
    QTcpSocket *socket = new QTcpSocket();
    socket->connectToHost(AimIp,AimPort);//连接函数
    if (socket->waitForConnected()) {
        // 连接成功
        qDebug() << "Connected to server!";

    } else {
        // 连接失败
        qDebug() << "连接失败";
    }

Qt 服务端被连接后接收显示并接收消息:

connect(&server, &QTcpServer::newConnection, this, [=]() {
        so = server.nextPendingConnection();
        QString ip = so->peerAddress().toString();
        quint16 port = so->peerPort();
        qDebug() << "New connection from " << ip << ":" << port;

        QString m = "<font color='blue'>有新的连接来自"+ip+":"+QString::number(port)+"</font>";
        ui->SeverState->append(m);
        //被连接后接收信息:
        connect(so, &QTcpSocket::readyRead, this, [=]() {
            QDateTime currentDateTime = QDateTime::currentDateTime();
            QString ip = so->peerAddress().toString();
            QByteArray data = so->readAll();//获取消息
            qDebug() << "Received data:" << data;
            QString mag1 = QString::fromUtf8(data);
            qDebug()<<currentDateTime;
            QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
            QString mag = "<font color='blue'>"+strDateTime+"收到来自"+ip+"的消息:"+mag1+"</font>";
            ui->talk->append(mag);
        });
    });

Qt 发送消息:

主要通过QTcpSocket的write()函数进行发送消息。

void Widget::toSend(){
    QString mag = this->ui->TextCin->toPlainText();
    so->write(mag.toUtf8());
    so->flush();
    so->waitForBytesWritten();
    socket->write(mag.toUtf8());
    socket->flush();
    socket->waitForBytesWritten();
    QDateTime currentDateTime = QDateTime::currentDateTime();
    QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
    QString smag = strDateTime+"向"+this->AimIp+"发送消息:"+mag;
    ui->talk->append(smag);
    ui->TextCin->clear();
}

最后:

这个东东只能进行简单的tcp通讯,而且要求连接的是同一局域网的两台设备才能进行交流,不过也的确是这样的,除非你有额外的设备什么的~
当然,如果你想整个QQ那种的东西出来的话,可以整个中间服务器,然后让不同的客户端都访问那个中间服务器,通过中间服务器进行交流~

成品:

链接:https://pan.baidu.com/s/1VqygMyjETYg5cRbLOvMbZQ?pwd=8rtr
提取码:8rtr

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt 实现简单的tcp网络通信 的相关文章

随机推荐

  • 用KEIL5打开KEIL4的文件

    有时候我们会遇到 xff0c 下载了KEIL5时需要打开KEIL4文件的时候 这时候 xff0c 我们需要将两个兼容一下 我遇到了挺多的问题 xff0c 下面自己总结一下 xff1a 我是按照开发板的指导书的步骤来进行的 上面写的 xff0
  • 恒流源电路

    一 恒流源概述 恒流源是指在功率范围内 xff0c 对外输出的电流基本是恒定的 二 恒流源特点 不因负载 输出电压 变化而改变 xff1b 不因环境温度变化而改变 xff1b 内阻为无限大 以使其电流可以全部流出到外面 xff1b 能够提供
  • 关于ST-Link V2 报错internal commend error的处理办法

    1 检查相关配置是否正确 确定接线没有问题 xff1a Vcc 接 Vcc GND 接 GND SWCLK 接 SWCLK SWDIO 接 SWDIO 首先 xff0c 确保电脑的CH驱动已经安装成功且正常运行 判断方法 xff1a 点击设
  • docker容器技术基础入门及LXC的配置

    docker容器技术基础入门及LXC的配置 1 docker简介1 2 容器与虚拟化的区别 xff1a 1 3 docker的三个基本概念1 3 1镜像1 3 2 分层储存1 3 3 容器1 3 4 仓库 2 docker产生的背景2 1
  • 简单易懂的51单片机LCD1602显示protues仿真程序

    时序图 仿真效果 include 34 AT89X51 h 34 typedef unsigned char u8 typedef unsigned int u16 define lcd1602 DB P3 sbit RS 61 P2 5
  • html5的思维导图--超详细

    下面是最近我学习总结的学习思维导图
  • 2023年天梯赛(l1 - l2全部题解)(第十二届)

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • c语言strtok函数完美实现

    看到网上好多错误的strtok实现 xff0c 也不能说错 xff0c 准确的说是没有完全的实现strtok xff0c 现自己写了下 xff0c 目前还没有找到bug xff0c 如果有不对的欢迎指出 大多数网上的strtok实现的代码跑
  • 使用vscode操作本地git

    学习目标 xff1a 使用vscode操作本地git 基础的git的命令 使用本地git进行版本穿梭 修改本地git的用户名和邮箱 git有三个状态 xff1a 工作区 暂存区 版本库 使用vscode操作本地git xff1a 1 首先
  • Linux环境下安装Docker

    1 安装Docker 1 1在linux系统中下载前置环境 1 安装wget命令 wget命令是Linux系统用于从Web下载文件的命令行工具 2 安装依赖环境 3 设置Docker镜像源 xff0c 因为默认的服务器很慢所以我选择国内镜像
  • VOC2007数据标签格式转COCO2017格式

    以下代码是将voc2007的数据标签格式转为coco2017数据标签格式 可直接基于voc2007的 xml所有文件进行处理 也可先转化为 txt文件路径之后再处理 此处我是直接基于 xml所有文件进行处理的 span class toke
  • SQLyog连接MYSQL时报错 Client does not support authentication protocol requested by server; consider upgra

    之前安装MYSQL8 0的时候安装的是绿色版 xff0c 在cmd中配置完所有参数之后 xff0c 在连接SQLyog的时候却报出了以下错误 翻译一下大致的意思为 xff1a 客户端不支持服务器请求的身份验证协议 xff1b 考虑升级MYS
  • 图神经网络对抗攻击的研究学习(一)

    目录 0 引入1 初窥1 1 图神经网络1 1 1 传统神经网络的不足1 1 2 图神经网络概况1 1 3 Graph Convolution Networks GCN 1 1 4 Graph Attention Networks GAT
  • 二叉树遍历方法——前、中、后序遍历(图解)

    目录 一 前序遍历 xff08 1 xff09 递归版本 xff08 2 xff09 非递归版本 二 中序遍历 xff08 1 xff09 递归版本 xff08 2 xff09 非递归版本 三 后序遍历 xff08 1 xff09 递归版本
  • VMware虚拟机安装Linux

    前言 接下来要分享一些Linux相关的内容 咱们来聊聊为啥要学Linux 首先 xff0c 运维靠这个吃饭 xff0c 测试要部署测试环境 大部分企业要用到Linux操作系统 xff0c 作为开发多少也要会是吧 所以 xff0c 他来了 一
  • MPU6050基本原理介绍及程序配置

    一 MPU6050简介 1 内部主要结构 xff1a 陀螺仪 加速度计 数字运动处理器DMP xff08 Digital Motion Processor xff09 PS MPU6050还含有第二IIC接口 xff0c 用于连接一个 第三
  • 2023年河北省天梯赛C语言 猜帽子游戏

    include lt stdio h gt int N K x int a 100 void solve int dui 61 0 int cuo 61 0 int mzuo 61 0 for int i 61 0 i lt N i 43
  • 树莓派4B环境配置

    前言 最近要用到树莓派 xff0c 荔枝整理了一份基础的树莓派4B配置总结 xff0c 有需要的大家自取 文章目录 前言 一 基础配置 1 1 烧录 1 2 进入桌面 1 3 开启SSH和VNC 二 更换国内源 三 查看python3版本并
  • Python之列表的基本操作

    目录 1 列表的创建与遍历 2 添加元素 3 删除元素 4 分片赋值 5 列表排序 完整代码 xff1a 本文的代码体为一个完整体 xff0c 即最开始的列表的创建与遍历中创建的列表 xff0c 为后续操作的主列表 如需从总体观看全部代码
  • Qt 实现简单的tcp网络通信

    文章目录 成品效果图 xff1a 代码 xff1a 工具头文件tool hUI文件代码 ui widget h 窗口头文件 widget h xff1a 窗口源文件widget cpp 相关代码说明 xff1a Qt获取本机ip Qt 打开