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通信(自定义TCP通信类) -> 正文阅读

[网络协议]QT之超简单的TCP通信(自定义TCP通信类)

TCP通信示例图

下图为TCP通信的简单界面,能是实现简单的TCP连接和发送信息
上图为TCP通信的简单界面,能是实现简单的TCP连接和发送信息

TCP使用前的准备

  1. 在pro文件中添加 “QT += network”(需要添加后才能使用网络通信)
  2. TCP发送可以通过write函数
  3. TCP读取可以通过read函数
  4. TCP收到新信息时会发出readyRead信号
  5. TCP服务端有新连接时会发出newConnection信号
  6. TCP服务端需要保存连接进来的客户端指针(方便通信)

自定义TCP通信类的两种方法

  1. 类继承对应的TCP类,通过this指针实现TCP操作(本文使用该方法)
  2. 类中包含对应的TCP类对象,通过该对象实现TCP操作
    注:以上两种方法最好不要合并使用,如果指针/对象使用不对有可能会出现如下类似的问题:QIODevice::write (QTcpSocket): device not open

源码(含注释)

TCP Server

CTcpServer.h
#ifndef CTCPSERVER_H
#define CTCPSERVER_H

#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>

class CTcpServer : public QTcpServer
{
    Q_OBJECT
public:
    explicit CTcpServer(QTcpServer *parent = nullptr);

    //发送信息到已连接的所有客户机
    void sendData(QString data);
signals:
    //通过该信号传递接收到的数据
    void recvDataSignal(QString data);
public slots:
    //当有新连接时的槽函数
    void newClient();
    //当有数据来时的槽函数
    void readyReadData();
private:
    QList<QTcpSocket *> m_clientList;   //存放客户端socket的容器
};

#endif // CTCPSERVER_H

CTcpServer.cpp
#include "CTcpServer.h"
#include <QTcpServer>

CTcpServer::CTcpServer(QTcpServer *parent) : QTcpServer(parent)
{
    //设置可以连接的ip和端口号(此处为任意ip且端口号为6666的可以连接);若要指定ip,设置第一个参数即可
    this->listen(QHostAddress::Any, 8866);
    //连接相关的信号槽
    connect(this, &CTcpServer::newConnection, this, &CTcpServer::newClient);
}

void CTcpServer::sendData(QString data)
{
    //遍历客户端列表,将数据发送到所有客户端中(类似广播)
    foreach (QTcpSocket *temp, m_clientList)
    {
        temp->write(data.toLocal8Bit(), data.length());
    }
}

void CTcpServer::newClient()
{
    //循环获取客户端socket
    while (this->hasPendingConnections())
    {
        QTcpSocket *clientTemp = this->nextPendingConnection();   //拿到当前的socket
        m_clientList.append(clientTemp);    //将当前socket添加到列表中(方便操作)
        connect(clientTemp, &QTcpSocket::readyRead, this, &CTcpServer::readyReadData);
    }
}

void CTcpServer::readyReadData()
{
	//拿到发送信号的客户端指针,通过该指针读取数据
    QTcpSocket *curClient = dynamic_cast<QTcpSocket *>(sender());
    emit recvDataSignal(curClient->readAll());
}

TCP Client

CTcpSocket.h
#ifndef CTCPSOCKET_H
#define CTCPSOCKET_H

#include <QObject>
#include <QTcpSocket>

class CTcpSocket : public QTcpSocket
{
    Q_OBJECT
public:
    explicit CTcpSocket(QTcpSocket *parent = nullptr);
    //通过改函数发送数据
    void sendData(QString data);
signals:
    //通过该信号传递接收到的数据
    void recvDataSignal(QString data);
public slots:
    //读取数据的槽函数
    void readyReadData();
};
#endif // CTCPSOCKET_H

CTcpSocket.cpp
#include "CTcpSocket.h"
#include <QHostAddress>

CTcpSocket::CTcpSocket(QTcpSocket *parent) : QTcpSocket(parent)
{
    //连接相应槽函数
    connect(this, &CTcpSocket::readyRead, this, &CTcpSocket::readyReadData);

    //指定ip且端口号为8866, (QHostAddress中指定的ip需本机存在或能连接到才可使用)
    this->connectToHost(QHostAddress("192.168.13.1"), 8866);
}

void CTcpSocket::sendData(QString data)
{
    this->write(data.toUtf8());
}

void CTcpSocket::readyReadData()
{
    emit recvDataSignal(this->readAll());
}

CMainWindow类(自定义TCP通信类的调用)

CMainWindow.h
#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H

#include <QMainWindow>
#include "CTcpServer.h"
#include "CTcpSocket.h"

namespace Ui {
class CMainWindow;
}

class CMainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit CMainWindow(QWidget *parent = 0);
    ~CMainWindow();

private slots:
    void on_connectBtn_clicked();	//连接
    void on_sendBtn_clicked();		//发送
    void on_appendData(QString data);	//将接收的数据显示

private:
    Ui::CMainWindow *ui;
    CTcpServer *m_server;
    CTcpSocket *m_client;
};
#endif // CMAINWINDOW_H

CMainWindow.cpp
#include "CMainWindow.h"
#include "ui_CMainWindow.h"

CMainWindow::CMainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::CMainWindow)
    , m_server(nullptr)
    , m_client(nullptr)

{
    ui->setupUi(this);
}

CMainWindow::~CMainWindow()
{
    if(nullptr != m_server)
    {
        delete m_server;
        m_server = nullptr;
    }

    if(nullptr != m_client)
    {
        delete m_client;
        m_client = nullptr;
    }

    delete ui;
}

void CMainWindow::on_connectBtn_clicked()
{
    //当连接后直接返回
    if("已连接" == ui->connectBtn->text())
        return;

    if(0 == ui->typeComboBox->currentIndex())
    {
        m_server = new CTcpServer;
        connect(m_server, &CTcpServer::recvDataSignal, this, &CMainWindow::on_appendData);
    }
    else
    {
        m_client = new CTcpSocket;
        connect(m_client, &CTcpSocket::recvDataSignal, this, &CMainWindow::on_appendData);
    }
    //设置按钮文本
    ui->connectBtn->setText("已连接");
}

void CMainWindow::on_sendBtn_clicked()
{
    if(0 == ui->typeComboBox->currentIndex())
    {
        m_server->sendData(ui->textEdit->toPlainText());
    }
    else
    {
        m_client->sendData(ui->textEdit->toPlainText());
    }
}

void CMainWindow::on_appendData(QString data)
{
    ui->textBrowser->append(data);
}

总结

TCP通信中不像UDP通信中两端都要绑定IP和端口号,并且TCP通信也更加安全。
在本文中不论时服务器还是客户端的IP和端口号都是代码写死的,若是需要能人性化的设置,在界面中添加两个QLineEdit且在自定义的通信类中添加设置IP和端口号的接的,调用该接口并将文本框中的对应值传入即可。若是有兴趣还可实现数据校验、重连、断开连接、指定客户端发送等功能。

相关文档:

自定义UDP类

注:本文仅为作者编程过程中所遇到的问题和总结,并非代表绝对正确,若有错误欢迎指出。
注:如有侵权,联系作者删除

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:57:52  更:2022-03-12 17:58:29 
 
开发: 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年11日历 -2024/11/26 6:23:50-

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