Qt TCP实现简单通信功能
作者:xundao_803817 发布时间:2021-07-07 02:16:30
本文实例为大家分享了Qt TCP实现简单通信的具体代码,供大家参考,具体内容如下
在.pro文件中添加网络模块 Qt += network
服务端:
1. 创建QTcpServer 对象,用于监听,创建套接字等;
QTcpServer * serverSocket = new QTcpServer(this);
2.进行监听,通过QTcpServer对象 QTcpServer::listen();
bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
例子:
// 获取单行输入框输入的数为端口号
short port = ui->lineEdit->text().toInt();
tcpServer->listen(QHostAddress::Any, port); // QHostAddress::Any表示自动绑定
3.使用信号槽,connect(), 判断是否有客户端来连接,QTcpServer::newConnection();
[signal] void QTcpServer::newConnection()
例子:
// 3.基于 QTcpServer::newConnection() 信号检测是否有新客户端连接
connect(tcpServer, &QTcpServer::newConnection, this, [=]()
? ? {
? ? ? ? // 创建用于通信的套接字
? ? ? ? // 4.如果有新的客户端连接调用 QTcpSocket* QTcpServer::nextPendingConnection()
? ? ? ? // 在通信编辑框中显示成功与客户端取得连接
? ? ? ? // 5.准备与客户端通信
? ? ? ? // 6.判断客户端是否断开连接 ? ?
? ? });
4.在步骤3的基础上,创建套接字,QTcpSocket socketServer = QTcpServer::nextPendingConnection();
5.在步骤3的基础上,使用信号槽connect(),判断是否接收客户端发了 的信息QTcpSocket::readyRead();
6. 在步骤5的基础上,通过套接字调用readAll() ,读取客户端发来的信息;
7.在步骤3的基础上,通过套接字判断客户端是否下线,关闭套接字;
客户端:
1. 创建套接字对象,用于通信 QTcpSocket *clientSocket = new QTcpSocket(this);
2. 调用信号槽,connect() ,判断是否成功连接服务端connected;
3. 调用信号槽,connect() , 判断是否接受来着服务端发来的信息 readyRead();
4. 在步骤3的基础上,利用套接字对象调用readAll() 方法,读取服务端发来的消息;
5. 利用套接字调用write() 方法,将消息发送给服务端;
6. 调用信号槽,connect() , 判断是否断开连接,释放套接字;
服务端代码:
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
?
#include "QDebug"
#include <QMessageBox>
?
MainWindow::MainWindow(QWidget *parent) :
? ? QMainWindow(parent),
? ? ui(new Ui::MainWindow)
{
? ? ui->setupUi(this);
?
? ? // 设置窗口名称
? ? setWindowTitle(QString("Server-TCP"));
? ? setWindowIcon(QIcon(QPixmap("D:\\BaiduNetdiskDownload\\Res WWW\\picture\\ico\\01_副本.png")));
?
? ? // 刚进来是将连接状态图片置成灰色的
? ? m_pixmap.load(QString("D:\\BaiduNetdiskDownload\\Res WWW\\picture\\ico\\01_副本_副本.png"));
?
? ? // 2.socket 通信
? ? //tcpSocket = new QTcpSocket();
? ? // 获取套接字
? ? // 服务端通信流程
? ? // 1.创建套接字服务器 QTcpServer对象
? ? tcpServer = new QTcpServer(this);
? ? // 2.通过QTcpServer对象设置监听,即QTcpServer::listen()
? ? // 3.基于 QTcpServer::newConnection() 信号检测是否有新客户端连接
? ? connect(tcpServer, &QTcpServer::newConnection, this, [=]()
? ? {
? ? ? ? // 成功连接则切换图片颜色
? ? ? ? m_pixmap.load(QString("D:\\BaiduNetdiskDownload\\Res WWW\\picture\\ico\\01_副本.png"));
?
? ? ? ? // 创建用于通信的套接字
? ? ? ? // 4.如果有新的客户端连接调用 QTcpSocket* QTcpServer::nextPendingConnection()
? ? ? ? tcpSocket = tcpServer->nextPendingConnection();
? ? ? ? // 在通信编辑框中显示成功与客户端取得连接
? ? ? ? ui->textEdit->append("成功与客户端取得连接!!!");
? ? ? ? // 5.准备与客户端通信
? ? ? ? connect(tcpSocket, &QTcpSocket::readyRead, this, [=]()
? ? ? ? {
? ? ? ? ? ? // 调用套接字读取客户端发的数据
? ? ? ? ? ? QString acceptText = tcpSocket->readAll(); // QByteArray 可以强制转成 QString
? ? ? ? ? ? // 将读取到的数据写到通信编辑框中
? ? ? ? ? ? ui->textEdit->append("客户端say:" + acceptText);
? ? ? ? });
?
? ? ? ? // 6.判断客户端是否断开连接
? ? ? ? connect(tcpSocket, &QTcpSocket::disconnected, this, [=]()
? ? ? ? {
? ? ? ? ? ? //QMessageBox(, QMessageBox::Warning, );
? ? ? ? ? ? QMessageBox::warning(this, "连接状态", "客户端已断开连接");
? ? ? ? ? ? tcpSocket->deleteLater();
? ? ? ? ? ? // 将连接状态图片置成灰色的
? ? ? ? ? ? m_pixmap.load(QString("D:\\BaiduNetdiskDownload\\Res WWW\\picture\\ico\\01_副本_副本.png"));
?
? ? ? ? ? ? //tcpServer->deleteLater();
? ? ? ? });
?
? ? });
?
? ? // 1.状态栏显示信息
? ? showMessageStatusBar();
}
?
MainWindow::~MainWindow()
{
? ? delete ui;
}
?
// 状态栏添加提示信息
void MainWindow::showMessageStatusBar()
{
? ? // 设置窗口名称
? ? //QWidget::windowTitleChanged("Server-TCP");
? ? //ui->statusBar->setWindowTitle();
?
? ? // 通过加载QLable给状态栏显示文本
? ? QLabel *pLable = new QLabel();
? ? QLabel *lableText = new QLabel(QString::fromUtf8("连接状态:"));
?
? ? //lableText->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
? ? //pLable->setMinimumWidth(this->width()/2);
?
? ? //= new QLabel(QString::fromUtf8("连接状态:"));
? ? // 设置lable标签的大小
? ? //pLable->setMinimumSize(pLable->sizeHint());
? ? pLable->setFixedSize(30, 30);
?
? ? m_pixmap.scaled(pLable->width(), pLable->height());
? ? // 显示图片
? ? pLable->setPixmap(m_pixmap);
? ? // 按比例缩小图片
?
? ? //pLable->setFixedSize(QSize(50,50));
? ? // 设置状态栏样式
? ? //ui->statusBar->setStyleSheet(QString("QString::item{border:0px")); ?// 不显示边框
? ? // 将标签加入到状态栏中
? ? ui->statusBar->addWidget(lableText);
? ? ui->statusBar->addPermanentWidget(pLable);//
}
?
// 处理点击启动服务器,进行监听
void MainWindow::on_pushButton_clicked()
{
? ? //qDebug() << "点击了 启动服务器按钮\n";
? ? // 获取输入框输入的数为端口号
? ? short port = ui->lineEdit->text().toInt();
? ? tcpServer->listen(QHostAddress::Any, port);
}
?
// 将数据发生给客户端
void MainWindow::on_pushButton_2_clicked()
{
? ? // 将发送数据编辑栏的文本通过套接字发生给客户端
? ? tcpSocket->write(ui->textEdit_2->toPlainText().toUtf8());
? ? // 需要将要发生的数据写到通信编辑栏中
? ? ui->textEdit->append("服务端say:" + ui->textEdit_2->toPlainText().toUtf8());
? ? // 清空发送消息编辑框
? ? ui->textEdit_2->clear();
}
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
?
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
?
?
namespace Ui {
class MainWindow;
}
?
class MainWindow : public QMainWindow
{
? ? Q_OBJECT
?
public:
? ? explicit MainWindow(QWidget *parent = nullptr);
? ? ~MainWindow();
?
? ? // 在状态栏中设置文本+图标
? ? void showMessageStatusBar();
?
? ? QTcpServer* tcpServer;
? ? QTcpSocket* tcpSocket;
?
private slots:
? ? void on_pushButton_clicked();
?
? ? void on_pushButton_2_clicked();
?
private:
? ? Ui::MainWindow *ui;
? ? // 用于加载图片路径
? ? QPixmap m_pixmap;
};
?
#endif // MAINWINDOW_H
程序UI
客户端:
client.cpp
#include "client.h"
#include "ui_client.h"
?
Client::Client(QWidget *parent) :
? ? QMainWindow(parent),
? ? ui(new Ui::Client)
{
? ? ui->setupUi(this);
?
? ? // 通信流程
? ? //1、创建套接字对象
? ? clientSocket = new QTcpSocket(this);
? ? //2、调用QTcpSocket::connectToHost() 绑定服务端IP和端口
?
? ? //3、通过套接字与服务端进行通信 收发
? ? // 判断是否成功连接服务端 开始读取服务端发来的信息
? ? connect(clientSocket, &QTcpSocket::readyRead, this, [=]()
? ? {
? ? ? ? // 通过套接字读取发来的信息
? ? ? ? QByteArray receiveAll = clientSocket->readAll();
? ? ? ? // 将获取到的信息显示到通信编辑栏中
? ? ? ? ui->textEdit_Record->append("服务端say:" + receiveAll);
? ? });
?
? ? // 开始的时候断开连接按钮置成不可用状态
? ? ui->disConBtn->setEnabled(false);
?
? ? // 判断是否连接成功
? ? connect(clientSocket, &QTcpSocket::connected, this, [=]()
? ? {
? ? ? ? // 将成功连接显示到通信记录编辑栏中
? ? ? ? ui->textEdit_Record->append("成功与服务端取得连接!!!");
? ? ? ? // 将断开连接置成可用状态
? ? ? ? ui->disConBtn->setEnabled(true);
? ? });
?
? ? // 判断是否断开连接
? ? connect(clientSocket, &QTcpSocket::disconnected, this, [=]()
? ? {
? ? ? ? // 将服务端断开连接显示到通信编辑框中
? ? ? ? ui->textEdit_Record->append("注意服务端已断开连接!!!");
? ? ? ? // 将连接服务端按钮置成不可用状态
? ? ? ? ui->conBtn->setEnabled(false);
? ? });
?
}
?
Client::~Client()
{
? ? delete ui;
}
?
// 点击按钮连接服务器,绑定地址与端口
void Client::on_conBtn_clicked()
{
? ? // 获取编辑框中的ip和端口
? ? unsigned short port = ui->lineEdit_port->text().toUShort();
? ? QString addr = ui->lineEdit_add->text();
? ? clientSocket->connectToHost(addr, port);
? ? // 需要将按钮置成不可用状态
? ? ui->conBtn->setEnabled(false);
}
?
// 断开连接
void Client::on_disConBtn_clicked()
{
? ? //clientSocket->disconnected();
? ? // 关闭套接字
? ? clientSocket->close();
? ? // 将客户端断开连接提示显示到通信编辑框中
? ? ui->textEdit_Record->append("注意客户端已断开连接!!!");
? ? // 将连接服务端按钮置成可用状态
? ? ui->conBtn->setEnabled(true);
}
?
// 点击按钮发送数据
void Client::on_sendBtn_clicked()
{
? ? // 获取发送信息编辑框的文本
? ? //ui->textEdit_Send->toPlainText().toUtf8();
?
? ? // 将获取到的信息发送给服务端
? ? clientSocket->write(ui->textEdit_Send->toPlainText().toUtf8());
? ? // 将发送的信息显示到通信记录编辑框中
? ? ui->textEdit_Record->append(ui->textEdit_Send->toPlainText().toUtf8());
? ? // 需要将发送编辑框清空缓存
? ? ui->textEdit_Send->clear();
}
client.h
#ifndef CLIENT_H
#define CLIENT_H
?
#include <QMainWindow>
#include <QTcpSocket>
?
namespace Ui {
class Client;
}
?
class Client : public QMainWindow
{
? ? Q_OBJECT
?
public:
? ? explicit Client(QWidget *parent = nullptr);
? ? ~Client();
?
private slots:
? ? void on_conBtn_clicked();
?
? ? void on_disConBtn_clicked();
?
? ? void on_sendBtn_clicked();
?
private:
? ? Ui::Client *ui;
?
? ? // 创建套接字
? ? QTcpSocket * clientSocket;
};
?
#endif // CLIENT_H
程序UI
来源:https://blog.csdn.net/m0_60178310/article/details/124989566


猜你喜欢
- 前言最近在参与一个银行项目-某银行安防系统-反洗钱需求的开发,银行项目的离不开身份证号码,身份证号码作为我国公民的唯一标识,有这非同寻常的意
- 阅读提示 具有mybatis基础,熟练使用mybatis-plus。概述 我们都知道,mybatis-plus是一个mybatis的增强
- 本文实例为大家分享了Java实现中英文词典功能的具体代码,供大家参考,具体内容如下功能如下:1、可以向词典中增加中英文单词,并提供修改和删除
- 一、ArrayList是什么ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元
- 比如:javascriptjavasejavaeejavame思路:定义一个计数器获取java第一次出现的位置从第一次出现位置后剩余的字符串
- 一、数组创建1.1 声明并赋值int[] a = {1,2,3};1.2 声明数组名开辟空间并且赋值int[] a;a = new int[
- 一、数组的基本用法1.什么是数组数组:存储一组相同数据类型的数据的集合。2.定义数组 int[] :int类型数组 do
- 一、前言做新应用就是这样,会遇到各种问题,昨天刚解决了加载某一个类时候抛出了 class is not visible from class
- 本文实例为大家分享了java绘制五子棋棋盘的具体代码,供大家参考,具体内容如下源码:import javax.imageio.ImageIO
- 一、SpringBoot 指定配置文件路径:在 SpringBoot 中,可以将配置文件放在 jar 包外面,这样可以方便地修改配置而不需要
- 很多朋友问小编springboot项目中怎么集成Swagger呢?swagger世界上最好的api管理工具前言我们为什么要使用api管理工具
- 本文实例为大家分享了Java工具类DateUtils的具体代码,供大家参考,具体内容如下import java.text.ParseExce
- 1.使用usb口输入的扫描枪,这里实现使用了winform首先创建一个CS文件using System;using System.Colle
- 1、普通用户与系统管理员用户的权限要有严格的区分。如果一个普通用户在使用查询语句中嵌入另一个Drop Table语句,那么是否允许
- 1.值类型值类型包括:数值类型,结构体,bool型,用户定义的结构体,枚举,可空类型。值类型的变量直接存储数据,分配在托管栈中。变量会在创建
- java 解决异常 2 字节的 UTF-8 序列的字节 2 无效的问题  
- 本文是vhr系列的第十二篇,项目地址 https://github.com/lenve/vhr邮件发送也是一个老生常谈的问题了,代码虽然简单
- 这里分享下我在日常开发中对 Gradle 的常用配置规则一、版本号配置当项目逐渐演进的过程中,主工程依赖的 Module 可能会越来越多,此
- 为了重用Fragment UI 组件,在设计中你应该通过定义每一个fragemnt自己的layout和行为,让fragment的自包含和模块
- 可以指定编码如:utf-8来写入和读取文件。如果文件编码未知,可以通过该方法先得到文件的编码后再指定正确的编码来读取,否则会出现文件乱码问题