广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >基于QT的TCP通信服务的实现
  • 499
分享到

基于QT的TCP通信服务的实现

2024-04-02 19:04:59 499人浏览 泡泡鱼
摘要

目录一、结构1.1 套接字1.2 Socket通信流程1.3 Qtcpsocket1.4 QtcpServer二、设计UI2.1 客户端UI2.2 服务器端UI三、核心代码四、效果图

一、结构

1.1 套接字

应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要 通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字 (Socket)的接口,区分不同应用程序进程间的网络通信和连接。

实际上套接字做的事情就是为我们通信的两端做一个连接

1.2 socket通信流程

对于TCP而言,socket通信的流程大概如下:

tcp通信

1.3 QTcpsocket

对于客户端我们就使用的这个QTcpsocket类去请求服务器端,我们先看官方给的文档可以知道:

在这里插入图片描述

使用该类需要#include <QTcpSocket>头文件,并且该类是继承QAbstractSocket类的,而且我们发现对于这个类没有新增很多的函数,那么我们就应该去看它的父类,果不其然,父类中有很多的函数,我们后面进行TCP通信其实也主要是用到父类的一些函数,所以看一下文档还是有必要的,对于每一个函数,你都能点进去看参数、以及描述

在这里插入图片描述

虽然QAbstractSocket有这么多的函数,但是我们实际上使用的函数就那么几个,我们后面一一介绍,我们现在先来说说QT客户端创建网络连接的流程:

1.我们需要new一个QTcpSocket的对象,当然初始化只需要将当前的obj传入即可,也就是this,然后给这个对象的readyRead创建一个凹槽做一些收到信号后的处理(比如将收到的数据显示在某个地方)。

2.通过connectToHost函数去连接服务器,函数中传入ipportip要强转为QHostAddress类)

3.通过调用waitForConnected函数,来判断服务器是否连接超时,一般设置1000,表示的是1s未连接就超时,通过官方的文档我们能知道如果返回的是true表示的是建立了连接,否则表示建立失败或未建立连接
注意的是这里,只有使用waitForConnected()后,QTcpSocket才真正尝试连接服务器,并返回是否连接的结果。

4.当我们的客户端接收到readyRead的信号,我们就可以通过readAll()函数读取服务器返回的信息,同样的我们也可以通过write()函数向服务器发送信息
注意的是这里服务端读到的数据是一个QByteArray类型的,我们写入的数据可以Qstring类型的,当然也可以是QByteArray

那么这就是客户端的通信流程了

1.4 QTcpServer

对于服务器端我们需要用到QTcpServer类,同样在官网的文档我们能得到这个类的一些基本信息:

在这里插入图片描述

服务端的流程:

1.首先创建一个QTcpServer类,并初始化,然后给这个对象的 QTcpServer::newConnection() 建立一个凹槽,用于处理与客户端建立连接后要做的一些事情,例如继续为QTcpSocket::readyRead创建一个凹槽进行数据读取操作、为QTcpSocket::disconnected创建凹槽用于对服务端失联后的操作……

2.通过listen(QHostAddress::Any,port)函数监听所有的ip请求

3.当有新的客户端连接服务器的时候,会自动触发newConnection()信号函数,然后我们可以通过通过QTcpSocket * nextPendinGConnection()成员函数来获取当前连接上的新的客户端类.然后再对QTcpSocket来进行信号槽绑定(这里可以写一个客户端的池但是我这里为了方便就只写了一个客户端连接的情况)

4.对于数据的读取的话,由于我们这里只写了一个客户端的情况,那么就可以直接给这个QTcpSocket对象绑定和客户端相同的事件就好

二、设计UI

我们直接使用QT Creator自带的绘制工具,简单绘制一下就好,界面不重要,重要是控件的objectName 经量设置合理一点,下面是我的设置:

2.1 客户端UI

在这里插入图片描述

2.2 服务器端UI

在这里插入图片描述

三、核心代码

对于客户端来说:mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTcpSocket>
#include <QLabel>
#include <QHostAddress>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    setWindowTitle(QString("客户端"));
    ui->setupUi(this);
    ui->port_2->setText("8899");
    ui->ip->setText("127.0.0.1");
    //刚开始 客户端的 [断开服务] 按钮不可用
    ui->disconnect->setDisabled(true);
    //创建一个监听器服务对象
    //Tcpserver
    m_tcp=new QTcpSocket(this);

    //客户端 被动的接收服务器信号
    connect(m_tcp,&QTcpSocket::readyRead,this,[=](){
        QByteArray array=m_tcp->readAll();
        ui->record->append("服务端说:"+array);
    });
    //客户端   断开
    connect(m_tcp,&QTcpSocket::disconnected,this,[=](){
        m_status->setPixmap(QPixmap(":/a/tmp/disconnect.png").scaled(20,20));
        ui->record->append("断开链接服务器");
        ui->connect->setDisabled(false);
        ui->disconnect->setDisabled(true);
    });
    //操作状态栏图标
    connect(m_tcp,&QTcpSocket::connected,this,[=](){
        m_status->setPixmap(QPixmap(":/a/tmp/connect.png").scaled(20,20));
        ui->record->append("已经链接成功服务器");

        //操作按钮互斥,链接成功了,自然链接按钮不能用只有断开按钮可以用
        ui->connect->setDisabled(true);
        ui->disconnect->setDisabled(false);
    });
    //增加一点动画效果   状态栏的颜色变化
   m_status =new QLabel;
   //状态栏的图片添加
   ui->statusbar->addWidget(new QLabel("链接状态:"));
   ui->statusbar->addWidget(m_status);
   //装到菜单状态栏


}

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

//点击监听服务,自然而然去启动监听服务


void MainWindow::on_send_clicked()
{
    //把发出信息框的数据拿到,通过socket套接字发送出去
    QString string=ui->sendmsg->toPlainText();
    m_tcp->write(string.toUtf8());
    ui->record->append("客户端说:"+string);
    ui->sendmsg->clear();
}

void MainWindow::on_connect_clicked()
{
    //获取 IP 端口   才能链接
   QString  ip=ui->ip->text();
   unsigned  short port=ui->port_2->text().toUShort();
   qDebug("click_on_connect state = %d\n",m_tcp->state());
   m_tcp->connectToHost(QHostAddress(ip),port);
   if(m_tcp->waitForConnected(1000)) {
        qDebug("connected !\n");
        ui->record->clear();
   }
   else
       qDebug("connect out time limit !\n");

}

void MainWindow::on_disconnect_clicked()
{
    qDebug("loc1 state = %d\n",m_tcp->state());
    m_tcp->disconnectFromHost();
    qDebug("loc2 state = %d\n",m_tcp->state());
    if(m_tcp->state() == QAbstractSocket::UnconnectedState
            || m_tcp->waitForDisconnected(1000))
        qDebug("Disconnected!\n");
    else
        qDebug("Disconnect fail!\n");
    m_tcp->close();
    ui->connect->setDisabled(false);
    ui->disconnect->setDisabled(false);
}

对于服务器来说:mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTcpServer>
#include <QTcpSocket>
#include <QLabel>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->port_2->setText("8899");
    //创建一个监听器服务对象
    //Tcpserver
    m_s=new QTcpServer(this);
    m_tcp = new QTcpSocket;
    //启动监听   通过点击监听按钮实现,并且在按钮转到的槽函数实现监听
    //上述完成监听,就等待用户/客户端的链接
    connect(m_s,&QTcpServer::newConnection,this,[=](){
        //状态栏变色
        m_status->setPixmap(QPixmap(":/a/tmp/connect.png").scaled(20,20));
        //程序到此步骤证明有用户链接,启用socket通信传输并解析数据
        //实例此次通信对象  nextPendingConnection得到一个可供通信的套接字对象
        m_tcp=m_s->nextPendingConnection();
        QString client_ip = m_tcp->peerAddress().toString().split("::ffff:")[1];
        quint16 client_port = m_tcp->peerPort();

        ui->record->append(tr("%1:%2 connected!\n").arg(client_ip).arg(client_port));
        //进行对象处理,检测传输的数据,利用connect对tcp套接字操作
        connect(m_tcp,&QTcpSocket::readyRead,this,[=](){
                QByteArray array = m_tcp->readAll();
                ui->record->append("客户端说:"+array);
        });

        //客户端断开操作
        connect(m_tcp,&QTcpSocket::disconnected,this,[=](){
            QString client_ip = m_tcp->peerAddress().toString().split("::ffff:")[1];
            quint16 client_port = m_tcp->peerPort();

            ui->record->append(tr("%1:%2 Disconnected!\n").arg(client_ip).arg(client_port));
            m_tcp->disconnectFromHost();
            if(m_tcp->state() == QAbstractSocket::UnconnectedState
                    || m_tcp->waitForDisconnected(1000))
                qDebug("Disconnected!\n");
            else
                qDebug("Disconnect fail!\n");
            m_status->setPixmap(QPixmap(":/a/tmp/disconnect.png").scaled(20,20));
        });
    });
    //增加一点动画效果   状态栏的颜色变化
   m_status =new QLabel;
   //状态栏的图片添加
   //m_status->setPixmap(QPixmap(":/a/tmp/connect.png").scaled(20,20));
   ui->statusbar->addWidget(new QLabel("链接状态:"));
   ui->statusbar->addWidget(m_status);
   //装到菜单状态栏
}

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

//点击监听服务,自然而然去启动监听服务
void MainWindow::on_setlisten_clicked()
{  setWindowTitle("服务器");
    //得到窗口 lineedit窗口的端口号
    unsigned  short  port=ui->port_2->text().toShort();
    //进行监听   ip   端口
    m_s->listen(QHostAddress::Any,port);
    ui->setlisten->setDisabled(true);
}

void MainWindow::on_send_clicked()
{
    //把发出信息框的数据拿到,通过socket套接字发送出去
    QString string=ui->sendmsg->toPlainText();
    m_tcp->write(string.toUtf8());
    ui->record->append("服务端说:"+string);
    ui->sendmsg->clear();
}

四、效果图

在这里插入图片描述

在这里插入图片描述

 到此这篇关于基于QT的TCP通信服务的实现的文章就介绍到这了,更多相关QT TCP通信内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 基于QT的TCP通信服务的实现

本文链接: https://www.lsjlt.com/news/148259.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 基于QT的TCP通信服务的实现
    目录一、结构1.1 套接字1.2 socket通信流程1.3 QTcpsocket1.4 QTcpServer二、设计UI2.1 客户端UI2.2 服务器端UI三、核心代码四、效果图...
    99+
    2022-11-13
  • 基于Qt的TCP实现通信
    本文实例为大家分享了基于Qt的TCP实现通信的具体代码,供大家参考,具体内容如下 一、tcp介绍 TCP是面向连接的可靠传输的协议,协议规定通信的双方是服务端和客户端的两个角色:服务...
    99+
    2022-11-13
  • Python基于socket实现TCP/IP客户和服务器通信
    目录前言简单的搭建服务器与客户端服务器客户端create_connection(更简易的客户端)前言 套接字除了用于分析网络地址等功能之外,还可以配置一个服务器,监听到来的消息。 比如你在网络上跟网络机器人聊天,你发...
    99+
    2022-06-02
    Python 客户和服务器通信 Python TCP/IP 通信
  • Java基于TCP协议的Socket通信
    目录简介TCP简介JAVA Socket简介SocketImpl介绍TCP 编程构造ServerSocket1.1 绑定端口1.2 设定客户连接请求队列的长度1.3 设定绑定的IP ...
    99+
    2022-11-12
  • QT实现TCP通信(服务器与客户端搭建)
    一、TCP通信框架 二、QT中的服务器操作 创建一个QTcpServer类对象,该类对象就是一个服务器调用listen函数将该对象设置为被动监听状态,监听时,可以监听指定的ip地址,也可以监听所有主机地址,可以通过指定端口号,也可以让服...
    99+
    2023-10-21
    服务器 tcp/ip 网络
  • C#基于Socket的TCP通信实现聊天室案例
    本文实例为大家分享了C#基于Socket的TCP通信实现聊天室的具体代码,供大家参考,具体内容如下 一、Socket(套接字)通信概念 套接字(socket)是通信的基石,用于描述I...
    99+
    2022-11-13
  • Python基于socket如何实现TCP/IP客户和服务器通信
    这篇文章主要为大家展示了“Python基于socket如何实现TCP/IP客户和服务器通信”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Python基于socket如何实现TCP/IP客户和服务...
    99+
    2023-06-15
  • 基于node的tcp客户端和服务端的简单通信
    目录1.简单介绍下TCP/IP2.服务端编程监听客户端连接接收数据和发送数据3.客户端编程4.一个小的登录系统1.简单介绍下TCP/IP TCP/IP是互联网相关协议的集合,分为以下...
    99+
    2022-11-13
  • Python 基于TCP 传输协议的网络通信实现方法
    目录1、基础概念1.1 协议1.2 IP 地址1.3 端口2、TCP 网络编程实现2.1 服务器端编程2.2 客户端编程3 总结1、基础概念 什么是网络编程? 指在网络环境中,如何实...
    99+
    2022-11-13
  • 如何使用C#基于Socket的TCP通信实现聊天室
    这篇文章给大家分享的是有关如何使用C#基于Socket的TCP通信实现聊天室的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。具体内容如下一.Socket(套接字)通信概念套接字(socket)是通信的基石,用于描述...
    99+
    2023-06-29
  • 基于Node.js的WebSocket通信实现
    node的依赖包 node中实现Websocket的依赖包有很多,websocket、ws均可,本文选取ws来实现,首先安装依赖 npm install ws 聊天室实例 假如A,B,C,D用户均通过...
    99+
    2022-06-04
    通信 Node js
  • TCP服务器—实现数据通信
    目录 前言 1.接口介绍 2.编写服务器 3.编写客户端 4.编译链接 5.测试 6.总结 前言         今天我们要介绍的是使用TCP协议实现数据通信,相比于之前写的UDP服务器实现数据信,在主体逻辑上并没有差别。客户端向服务...
    99+
    2023-08-31
    tcp/ip 服务器 网络
  • Java中TCP通信的实现
    0、TCP通信 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议, 如果使用了 WireShark 工具,可以看到一次TCP连接建立时的整个过程。 1...
    99+
    2023-09-02
    java tcp/ip 开发语言
  • QT5实现简单的TCP通信的实现
    目录一、客户端二、服务器三、运行结果这段时间用到了QT的TCP通信,做了初步的学习与尝试,编写了一个客户端和服务器基于窗口通信的小例程。 使用QT的网络套接字需要.pro文件中加入一...
    99+
    2022-11-13
  • TCP实现服务器和客户端通信
    目录 TCP介绍 代码实现 server(服务器端) 代码分析 client(客户端) 代码分析 结果展示 TCP介绍 TCP (Transmission Control Protocol) 是一种面向连接的协议,用于在计算机网络中传...
    99+
    2023-09-06
    tcp/ip 服务器 网络
  • Python基于socket实现TCP客户端和服务端
    目录一、基于socket实现的TCP客户端二、基于socket实现的TCP服务端三、socket实现的多任务版TCP服务端1、面向对象版本一、基于socket实现的TCP客户端 im...
    99+
    2022-11-10
  • QT串口通信的实现方法
    前言:如果用qt写程序作为上位机,然后通过和usb和下位机通信的时候,就需要用到qt中的串口通信了。 使用qt中的串口通信的时候需要用到的两个头文件分别为: #include &...
    99+
    2022-11-12
  • QT5如何实现简单的TCP通信
    这篇文章主要介绍“QT5如何实现简单的TCP通信”,在日常操作中,相信很多人在QT5如何实现简单的TCP通信问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”QT5如何实现简单的TCP通信”的疑惑有所帮助!接下来...
    99+
    2023-06-30
  • Python基于socket怎么实现TCP客户端和服务端
    这篇文章主要讲解了“Python基于socket怎么实现TCP客户端和服务端”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python基于socket怎么实现TCP客户端和服务端”吧!一、基...
    99+
    2023-06-30
  • Qt实现两个独立窗口的信号通信
    本文实例为大家分享了Qt实现两个独立窗口的信号通信的具体代码,供大家参考,具体内容如下 知识点 Qt两个窗口的建立、窗口的通信、处理子窗口的信号、信号的重载、Lamber表达式、自定...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作