IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Qt Tcp网络编程 -> 正文阅读

[网络协议]Qt Tcp网络编程

概念

TCP/IP协议在一定程度上参考了OSI的体系结构。OSI模型共有七层,从下到上分别是物理层、数据链路层、网络层、运输层、会话层、表示层和应用层。但是这显然是有些复杂的,所以在TCP/IP协议中,它们被简化为了四个层次。来自百度

Tcp通信的特点

1 面向连接:是指发送数据之前必须在两端建立连接,“三次握手”
2.提供可靠的服务:Tcp通过校验和,使用重传控制、流量控制和拥塞控制
3.每条传输连接只能有两个端点,只能进行点对点的数据传输,不支持多播和广播传输方式
4…面向字节流
套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

效果

在这里插入图片描述

QT提供了QTcpSocket类,可以方便的实现一个客户端;
.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_btnClearRec_clicked();

    //接受数据
    void receiveData();

    //处理错误信息
    void ReadError(QAbstractSocket::SocketError);

    void on_btn_Connect_clicked();

    void on_btn_DisConnect_clicked();

    void on_btnSend_clicked();

private:
    Ui::Widget *ui;
    //套接字    
    QTcpSocket *m_Socket = nullptr;


};
#endif // WIDGET_H

.cpp

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

    ui->btn_DisConnect->setEnabled(false);

    m_Socket = new QTcpSocket(this);

    //设置代理模式
    m_Socket->setProxy(QNetworkProxy::NoProxy);

    //读取新数据信号槽
    connect(m_Socket, SIGNAL(readyRead()), this, SLOT(receiveData()));

    //连接错误信息信号槽
    connect(m_Socket, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(ReadError(QAbstractSocket::SocketError)));

    //调用connectToHost()并成功建立连接之后发出此信号。
    connect(m_Socket, &QTcpSocket::connected,[&]{
        ui->textEdit_Receive->append(QStringLiteral("连接成功"));
    });

    //当套接字断开连接时发出此信号
    connect(m_Socket, &QTcpSocket::disconnected,[&]{
        ui->textEdit_Receive->append(QStringLiteral("断开连接"));
    });


}

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


void Widget::on_btnClearRec_clicked()
{
    ui->textEdit_Receive->clear();
}

void Widget::receiveData()
{
    QByteArray buffer = m_Socket->readAll();
    if(!buffer.isEmpty())
    {
       ui->textEdit_Receive->append(buffer);
    }
}

void Widget::ReadError(QAbstractSocket::SocketError)
{
    m_Socket->disconnectFromHost();
    ui->textEdit_Receive->append(m_Socket->errorString());
}

void Widget::on_btn_Connect_clicked()
{
    //连接服务器
    m_Socket->connectToHost(ui->lineEditI_Ip->text(), ui->lineEdit_Port->text().toInt());
    if (m_Socket->waitForConnected(1000))
    {
        ui->btn_Connect->setEnabled(false);
        ui->btn_DisConnect->setEnabled(true);

    }
}

void Widget::on_btn_DisConnect_clicked()
{
    //断开连接
    m_Socket->disconnectFromHost();
    if (m_Socket->state() == QAbstractSocket::UnconnectedState
         || m_Socket->waitForDisconnected(1000))
    {
     ui->btn_Connect->setEnabled(true);
     ui->btn_DisConnect->setEnabled(false);
    }
}

void Widget::on_btnSend_clicked()
{
    QString data = ui->textEdit_Send->toPlainText();
    if(data != "")
    {
        //发送数据
        m_Socket->write(data.toLatin1());
    }
}

QT提供了QTcpServer类,可以方便的实现一个服务端;
.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QNetworkInterface>
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 receiveData();

    void on_btn_Connect_clicked();

    void on_btn_DisConnect_clicked();

    void on_btnSend_clicked();

private:
    Ui::Widget *ui;
    //服务器
    QTcpServer *m_tcpServer = nullptr;
    
    //套接字
    QTcpSocket *m_tcpSocket = nullptr;

};
#endif // WIDGET_H

.cpp文件

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

    m_tcpServer = new QTcpServer(this);
    m_tcpSocket = new QTcpSocket(this);
    
    //设置代理模式
    m_tcpSocket->setProxy(QNetworkProxy::NoProxy);

    //每当有新的连接可用时,就会发出此信号。
    connect(m_tcpServer, &QTcpServer::newConnection, this,[&]{
        m_tcpSocket = m_tcpServer->nextPendingConnection();
        
    //该信号在设备当前读取通道中每次有新的数据可用时发出。
    connect(m_tcpSocket, &QTcpSocket::readyRead, this, &Widget::receiveData);
    
    //当套接字断开连接时发出此信号。
    connect(m_tcpSocket, &QTcpSocket::disconnected,this,[&]{
            ui->textEdit_Rec->append(QStringLiteral("断开连接"));
        });
    });
    
    //获取本地IP
    ui->lineEditI_Ip->setText(QNetworkInterface().allAddresses().at(1).toString());   
}

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

void Widget::receiveData()
{
     //从设备读取所有剩余的数据,并将其作为字节数组返回。
     QByteArray buffer = m_tcpSocket->readAll();
     ui->textEdit_Rec->append(buffer);
}

void Widget::on_btn_Connect_clicked()
{
    //服务器监听传入的连接。当port为0时,
    //系统自动选择端口。如果address为QHostAddress::Any,服务器将监听所有网络接口。
    bool ok = m_tcpServer->listen(QHostAddress::Any, ui->lineEdit_Port->text().toInt());
    if(ok)
    {
        ui->btn_Connect->setEnabled(false);
        ui->btn_DisConnect->setEnabled(true);
    }
}

void Widget::on_btn_DisConnect_clicked()
{
    //关闭socket
    m_tcpSocket->disconnectFromHost();
    
    //等待直到套接字断开连接。
    //如果连接已经断开,这个函数返回true;否则返回false。
    bool ok = m_tcpSocket->waitForDisconnected(1000);
    
    ui->btn_DisConnect->setEnabled(false);
    ui->btn_Connect->setEnabled(true);
    
    //不再监听端口
    m_tcpServer->close();     
    m_tcpSocket->destroyed();
}

void Widget::on_btnSend_clicked()
{
    QString data = ui->textEdit_Send->toPlainText();
    if(data != "")
    {
        //发送数据
        m_tcpSocket->write(data.toLatin1());
    }
}

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 18:20:11  更:2022-04-18 18:20:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/30 3:07:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码