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工作原理

Tcp是面向连接的一种流式通信,能够提供可靠的通信连接,使一台客户机发出的字节流无差错地送达网络上的其他计算器。如果是对可靠性要求高的数据通信系统则需要使用Tcp传输数据,但是要发送数据,则必须首先建立连接。

二、TCP编程模型

1)首先启动服务器,成功后启动客户端;

2)客户端与服务器进行三次握手后建立连接;

3)客户端向服务端发送请求;

4)服务端发送给客户端响应;

5)多次循环,知道通讯结束,最后关闭网络连接。

三、TCP通信传输类型:

1)基于行的方式

?????基于行的数据通信协议用于一般用于纯文本数据的通信,每一行数据以换行符结束。

2)基于数据块方式

?????基于块的数据通信协议用于一般的二进制数据传输,需要自定义具体格式。

四、代码示例:

1、效果图

2、代码示例

1)TCP服务端

mainwindow.h?:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLabel>
#include <QTcpServer>
#include <QTcpSocket>
#include <QAbstractSocket>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
? ? Q_OBJECT

public:
? ? explicit MainWindow(QWidget *parent = 0);
? ? ~MainWindow();
? ? QString ?getLocalIP();

private slots:
? ? void onNewConnection();
? ? void onSocketStateChange(QAbstractSocket::SocketState);
? ? void onClientConnected();
? ? void onClientDisconnected();
? ? void onSocketReadyRead();
? ? void on_connectBtn_clicked();
? ? void on_disconnectBtn_clicked();
? ? void on_sendBtn_clicked();
? ? void on_clearBtn_clicked();

private:
? ? Ui::MainWindow *ui;
? ? QLabel ?*labListen;
? ? QLabel ?*labSocketState;
? ? QTcpServer ?*tcpServer;
? ? QTcpSocket ?*tcpSocket;
};

#endif // MAINWINDOW_H

mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHostInfo>

MainWindow::MainWindow(QWidget *parent) :
? ? QMainWindow(parent),
? ? ui(new Ui::MainWindow)
{
? ? ui->setupUi(this);
? ? QString localIP = getLocalIP();
? ? ui->ipLineEdit->setText(localIP);
? ? ui->portLineEdit->setText("1000");

? ? labListen = new QLabel(QString::fromLocal8Bit("监听状态:"));
? ? labListen->setMinimumWidth(150);
? ? ui->statusBar->addWidget(labListen);

? ? labSocketState = new QLabel(QString::fromLocal8Bit("Socket状态:"));
? ? labSocketState->setMinimumWidth(200);
? ? ui->statusBar->addWidget(labSocketState);

? ? tcpServer = new QTcpServer(this);
? ? connect(tcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
}

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

QString MainWindow::getLocalIP()
{
? ? 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 hostAddr = addList.at(i);
? ? ? ? ? ? if(QAbstractSocket::IPv4Protocol == hostAddr.protocol())
? ? ? ? ? ? {
? ? ? ? ? ? ? ? localIP = hostAddr.toString();
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? return localIP;
}

void MainWindow::onNewConnection()
{
? ? tcpSocket = tcpServer->nextPendingConnection();
? ? 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)
{
? ? switch (socketState)
? ? {
? ? case QAbstractSocket::UnconnectedState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: UnconnectedState"));
? ? ? ? break;
? ? case QAbstractSocket::HostLookupState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: HostLookupState"));
? ? ? ? break;
? ? case QAbstractSocket::ConnectingState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: ConnectingState"));
? ? ? ? break;
? ? case QAbstractSocket::ConnectedState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: ConnectedState"));
? ? ? ? break;
? ? case QAbstractSocket::BoundState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: BoundState"));
? ? ? ? break;
? ? case QAbstractSocket::ClosingState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: ClosingState"));
? ? ? ? break;
? ? case QAbstractSocket::ListeningState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: ListeningState"));
? ? ? ? break;
? ? default:
? ? ? ? break;
? ? }
}

void MainWindow::onClientConnected()
{
? ? ui->plainTextEdit->appendPlainText("**client socket connected");
? ? ui->plainTextEdit->appendPlainText("**peer address:" + tcpSocket->peerAddress().toString());
? ? ui->plainTextEdit->appendPlainText("**peer port:" + QString::number(tcpServer->serverPort()));
? ? ui->connectBtn->setEnabled(false);
? ? ui->disconnectBtn->setEnabled(true);
}

void MainWindow::onClientDisconnected()
{
? ? ?ui->plainTextEdit->appendPlainText("**client socket disconnected");
? ? ?tcpSocket->deleteLater();
}

void MainWindow::onSocketReadyRead()
{
//一、基于行的网络传输
// ? ?while(tcpSocket->canReadLine())
// ? ?
// ? ? ? ?ui->plainTextEdit->appendPlainText("[client] " + tcpSocket->readLine());
// ? ?}
? ? //二、基于块的网络传输
? ? //1)方案一:
// ? ?while(tcpSocket->bytesAvailable() > 0)
// ? ?{
// ? ? ? ?ui->plainTextEdit->appendPlainText("[client] " + tcpSocket->readAll());
// ? ?}
? ? //2)方案二:
? ? while (!tcpSocket->atEnd())
? ? {
? ? ? ? ?QByteArray data = tcpSocket->read(255);
? ? ? ? ?ui->plainTextEdit->appendPlainText("[client] " + data);
? ? }
}

void MainWindow::on_connectBtn_clicked()
{
? ? QString IP = ui->ipLineEdit->text();
? ? quint16 port = ui->portLineEdit->text().toUInt();

? ? if(!tcpServer->listen(QHostAddress(IP), port))
? ? {
? ? ? ? ui->plainTextEdit->appendPlainText(QString::fromLocal8Bit("服务器监听失败!"));
? ? }
? ? else
? ? {
? ? ? ? ui->plainTextEdit->appendPlainText(QString::fromLocal8Bit("服务器监听成功!"));
? ? ? ? ui->connectBtn->setEnabled(false);
? ? ? ? ui->disconnectBtn->setEnabled(true);
? ? ? ? labListen->setText(QString::fromLocal8Bit("监听状态,正在监听"));
? ? }
}

void MainWindow::on_disconnectBtn_clicked()
{
? ? if(tcpServer->isListening())
? ? {
? ? ? ? tcpServer->close();//停止监听
? ? ? ? ui->connectBtn->setEnabled(true);
? ? ? ? ui->disconnectBtn->setEnabled(false);
? ? ? ? labListen->setText(QString::fromLocal8Bit("监听状态:已停止监听"));
? ? }
}

void MainWindow::on_sendBtn_clicked()
{
? ? QString msg = ui->MsgLineEdit->text();
? ? ui->plainTextEdit->appendPlainText("[server] " + msg);
? ? ui->MsgLineEdit->clear();
? ? ui->MsgLineEdit->setFocus();

// ? ?QByteArray dataArray = msg.toUtf8();
// ? ?dataArray.append('\n');
// ? ?tcpSocket->write(dataArray);
? ? QByteArray dataArray = msg.toUtf8();
? ? tcpSocket->write(dataArray);
? ? tcpSocket->flush();
}

void MainWindow::on_clearBtn_clicked()
{
? ? ui->MsgLineEdit->clear();
? ? ui->plainTextEdit->clear();
}

2)客户端

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QLabel>
#include <QAbstractSocket>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
? ? Q_OBJECT

public:
? ? explicit MainWindow(QWidget *parent = 0);
? ? ~MainWindow();
? ? QString getLocalIP();
private slots:
? ? void onConnected();
? ? void onDisconnected();
? ? void onSocketStateChange(QAbstractSocket::SocketState);
? ? void onSocketReadyRead();
? ? void on_connectBtn_clicked();

? ? void on_disconnectBtn_clicked();

? ? void on_sendBtn_clicked();

? ? void on_clearBtn_clicked();

private:
? ? Ui::MainWindow *ui;
? ? QTcpSocket ?*tcpClient;
? ? QLabel *labSocketState;

};

#endif // MAINWINDOW_H

mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHostInfo>

MainWindow::MainWindow(QWidget *parent) :
? ? QMainWindow(parent),
? ? ui(new Ui::MainWindow)
{
? ? ui->setupUi(this);
? ? this->setWindowTitle(QString::fromLocal8Bit("客户端"));

? ? QString localIP = getLocalIP();
? ? ui->ipLineEdit->setText(localIP);
? ? ui->portLineEdit->setText("1000");

? ? labSocketState = new QLabel(QString::fromLocal8Bit("Socket状态:"));
? ? labSocketState->setMinimumWidth(250);
? ? ui->statusBar->addWidget(labSocketState);
? ? //tcpSocket
? ? tcpClient = new QTcpSocket(this);

? ? connect(tcpClient, SIGNAL(connected()), this, SLOT(onConnected()));
? ? connect(tcpClient, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
? ? connect(tcpClient, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
? ? connect(tcpClient, SIGNAL(readyRead()), this, SLOT(onSocketReadyRead()));
}

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

QString MainWindow::getLocalIP()
{
? ? 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 hostAddr = addList.at(i);
? ? ? ? ? ? ?if(QAbstractSocket::IPv4Protocol == hostAddr.protocol())
? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ?localIP = hostAddr.toString();
? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ?}
? ? ? ? }
? ? }
? ? return localIP;
}

void MainWindow::onConnected()
{
? ? ui->plainTextEdit->appendPlainText(QString::fromLocal8Bit("**已连接到服务器"));
? ? ui->plainTextEdit->appendPlainText("**peer address:" + tcpClient->peerAddress().toString());
? ? ui->plainTextEdit->appendPlainText("**peer port:" + QString::number(tcpClient->peerPort()));
? ? ui->connectBtn->setEnabled(false);
? ? ui->disconnectBtn->setEnabled(true);
}

void MainWindow::onDisconnected()
{
? ? ui->plainTextEdit->appendPlainText(QString::fromLocal8Bit("**已断开与服务器连接"));
? ? ui->connectBtn->setEnabled(true);
? ? ui->disconnectBtn->setEnabled(false);
}

void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)
{
? ? switch (socketState)
? ? {
? ? case QAbstractSocket::UnconnectedState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: UnconnectedState"));
? ? ? ? break;
? ? case QAbstractSocket::HostLookupState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: HostLookupState"));
? ? ? ? break;
? ? case QAbstractSocket::ConnectingState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: ConnectingState"));
? ? ? ? break;
? ? case QAbstractSocket::ConnectedState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: ConnectedState"));
? ? ? ? break;
? ? case QAbstractSocket::BoundState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: BoundState"));
? ? ? ? break;
? ? case QAbstractSocket::ClosingState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: ClosingState"));
? ? ? ? break;
? ? case QAbstractSocket::ListeningState:
? ? ? ? labSocketState->setText(QString::fromLocal8Bit("socket 状态: ListeningState"));
? ? ? ? break;
? ? default:
? ? ? ? break;
? ? }
}

void MainWindow::onSocketReadyRead()
{
? //一、基于行的网络传输
// ? ?while(tcpClient->canReadLine())
// ? ?{
// ? ? ? ui->plainTextEdit->appendPlainText("[Server] " + tcpClient->readLine());
// ? ?}
? ? //二、基于块的网络传输
? ? //1)方案一:
// ? ?while(tcpClient->bytesAvailable() > 0)
// ? ?{
// ? ? ? ?ui->plainTextEdit->appendPlainText("[Server] " + tcpClient->readAll());
// ? ?}
? ? //2)方案二:
? ? while (!tcpClient->atEnd())
? ? {
? ? ? ? ?QByteArray data = tcpClient->read(255);
? ? ? ? ?ui->plainTextEdit->appendPlainText("[Server] " + data);
? ? }
}

void MainWindow::on_connectBtn_clicked()
{
? ? QString addrIP = ui->ipLineEdit->text();
? ? quint16 port = ui->portLineEdit->text().toUInt();
? ? tcpClient->connectToHost(addrIP, port);
}

void MainWindow::on_disconnectBtn_clicked()
{
? ? if(tcpClient->state() == QAbstractSocket::ConnectedState)
? ? {
? ? ? ? tcpClient->disconnectFromHost();
? ? }
}

void MainWindow::on_sendBtn_clicked()
{
? ? QString msg = ui->MsgLineEdit->text();
? ? ui->plainTextEdit->appendPlainText("[Client] " + msg);
? ? ui->MsgLineEdit->clear();
? ? ui->MsgLineEdit->setFocus();

// ? ?QByteArray dataArray = msg.toUtf8();
// ? ?dataArray.append('\n');
// ? ?tcpClient->write(dataArray);

? ? QByteArray dataArray = msg.toUtf8();
? ? tcpClient->write(dataArray);
? ? tcpClient->flush();
}

void MainWindow::on_clearBtn_clicked()
{
? ? ui->MsgLineEdit->clear();
? ? ui->plainTextEdit->clear();
}

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

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