1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Qt网络编程-简易版TcpServer入门Demo(2)

Qt网络编程-简易版TcpServer入门Demo(2)

时间:2018-12-31 15:47:52

相关推荐

Qt网络编程-简易版TcpServer入门Demo(2)

Qt网络编程-简易版TcpServer入门Demo(2)🦏

文章目录

Qt网络编程-简易版TcpServer入门Demo(2)🦏1、概述🐅2、TCP服务端流程图🐴3、 关键信号🐕4、 关键函数 🐶5、主要代码🦍6、实现效果🐒7、源代码🐈

1、概述🐅

第一,绝对不意气用事;

第二,绝对不放过任何一个注释;

第三,绝对保证代码的简洁明了。🤘

为了便于学习,在这个Demo里会尽可能简单的实现TCP服务端功能,尽可能少的引入其它功能,只保留了基本功能,所以可能会有一些bug。

实现功能:

监听1个Tcp客户端连接功能,多余的连接自动断开;数据接收功能;数据发送功能

2、TCP服务端流程图🐴

TCP服务端除了监听连接部分外,其它的和TCP客户端基本一样。

3、 关键信号🐕

4、 关键函数 🐶

5、主要代码🦍

注意:在.pro文件里添加QT += network,否则编译失败。

.h文件

/******************************************************************************* @文件名simpletcpserver.h* @功能 简易的TCP服务端Demo,只保留接听TCP(1个)客户端连接/断开、 数据发送、接收功能** @开发者mhf* @邮箱 1603291350@* @时间 /04/17* @备注*****************************************************************************/#ifndef SIMPLETCPSERVER_H#define SIMPLETCPSERVER_H#include <QWidget>#include <QTcpServer>namespace Ui {class SimpleTcpServer;}class SimpleTcpServer : public QWidget{Q_OBJECTpublic:explicit SimpleTcpServer(QWidget *parent = nullptr);~SimpleTcpServer();private slots:void on_newConnection();void on_disconnected();void on_readyRead();void on_but_connect_clicked();void on_but_send_clicked();private:Ui::SimpleTcpServer *ui;QTcpServer* m_server = nullptr; // TCP服务端对象QTcpSocket* m_client = nullptr; // 连接成功的客户端};#endif // SIMPLETCPSERVER_H

.cpp文件

#include "simpletcpserver.h"#include "ui_simpletcpserver.h"#include <qtcpsocket.h>SimpleTcpServer::SimpleTcpServer(QWidget *parent) :QWidget(parent),ui(new Ui::SimpleTcpServer){ui->setupUi(this);this->setWindowTitle("简易版本TCP 服务端Demo");m_server = new QTcpServer(this);connect(m_server, &QTcpServer::newConnection, this, &SimpleTcpServer::on_newConnection); // 监听新的客户端连接}SimpleTcpServer::~SimpleTcpServer(){delete ui;}void SimpleTcpServer::on_but_connect_clicked(){if(!m_server->isListening())// 判断是否正在监听连接{// 告诉服务器侦听地址和端口上的传入连接。如果端口为0,则会自动选择一个端口。// 如果地址是QHostAddress::Any,服务器将监听所有网络接口。bool ret = m_server->listen(QHostAddress::Any, ui->spin_localPort->value());if(ret){ui->but_connect->setText("停止");}else{qDebug() << QString("tcpServer绑定监听IP、端口失败:%1 %2").arg(m_server->errorString()).arg(m_server->serverError());}}else{m_client->abort();m_server->close();ui->but_connect->setText("开始监听");}}/*** @brief 如果有新的TCP客户端发起连接,则会在这个函数中返回连接成功的QTcpSocket;* 这里只保留第一个连接成功的客户端,其它的自动断开连接*/void SimpleTcpServer::on_newConnection(){QTcpSocket* tcpSocket = m_server->nextPendingConnection(); // 存在内存泄漏,最好使用时通过hasPendingConnections判断是否有未返回的连接if(tcpSocket){if(m_client) // 如果已经有连接的 客户端,则断开后面所有的连接{tcpSocket->deleteLater();return;}m_client = tcpSocket;connect(tcpSocket, &QTcpSocket::disconnected, this, &SimpleTcpServer::on_disconnected); // 断开连接connect(tcpSocket, &QTcpSocket::readyRead, this, &SimpleTcpServer::on_readyRead); // 接收客户端发来的数据}}/*** @brief 断开连接*/void SimpleTcpServer::on_disconnected(){disconnect(m_client, &QTcpSocket::disconnected, this, &SimpleTcpServer::on_disconnected);// 断开绑定的信号槽disconnect(m_client, &QTcpSocket::readyRead, this, &SimpleTcpServer::on_readyRead);//delete m_client;// 这里不能用delete,否则在vs里会报错 0x00007FFBF870A1CE (Qt5Networkd.dll)处(位于 QMNetwork.exe 中)引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。QTcpSocket* tcpSocket = m_client;m_client = nullptr; // 先将m_client置空,因为deleteLater不会置空tcpSocket->deleteLater(); // 移除已经断开连接的Client(注意这里不能使用delete,否则在vs中会报错),但这种方式不会置为 空}/*** @brief 接收数据,这里和TCP Client是一样的*/void SimpleTcpServer::on_readyRead(){QByteArray dataArr = m_client->readAll(); // 一次性读取缓存中所有数据if(dataArr.count() <= 0) // 没有读取到数据{return;}ui->text_recv->append(dataArr); // 显示读取到的数据}/*** @brief 发送数据,这里和TCP Client是一样的*/void SimpleTcpServer::on_but_send_clicked(){if(!m_client) return;// 判断是否为空,如果为空则未连接if(m_client->state() != QAbstractSocket::ConnectedState) return; // 判断TCP是否已连接,如果没有连接则不发送数据QString str = ui->text_send->toPlainText(); // 获取输入框的内容qint64 len = m_client->write(str.toUtf8());// 发送数据,toUtf8()是为了支持发送中文,但是如果接收端编码方式不同则中文可能显示乱码if(len < 0){qWarning() <<"发送失败!";}}

6、实现效果🐒

7、源代码🐈

gitee

github

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。