QT5.14.2自带Examples:Local Fortune Server/Client
概述
这是两个示例,需要配合使用。可以在本机为两个应用程序建立socket通信。
主要是对QLocalServer和QLocalSocket的使用。
QLocalServer
- 调用 listen(),让服务器开始监听本地套接字上指定关键字的连接。
- 每次客户端连接到服务器时,都会发出newConnection()信号。
- 调用nextPendingConnection()将挂起的连接接受为已连接的QLocalSocket。该函数返回一个指向QLocalSocket的指针,用于与客户端通信。
QLocalSocket
建立连接后,通过套接字收发数据。
Server 程序
Server 类定义
#ifndef SERVER_H
#define SERVER_H#include <QDialog>QT_BEGIN_NAMESPACE
class QLabel;
class QPushButton;
class QLocalServer;
QT_END_NAMESPACEclass Server : public QDialog
{Q_OBJECTpublic:explicit Server(QWidget *parent = nullptr);private slots:void sendFortune();private://QLocalServer接受传入的本地套接字连接。QLocalServer *server;///抽取的签筒,里面放了各种签QStringList fortunes;
};#endif
Server类实现
#include "server.h"#include <QtWidgets>
#include <QtNetwork>Server::Server(QWidget *parent): QDialog(parent)
{setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);server = new QLocalServer(this);//调用 listen()让服务器开始监听指定关键字(fortune)上的传入连接。if (!server->listen("fortune")) {QMessageBox::critical(this, tr("Local Fortune Server"),tr("Unable to start the server: %1.").arg(server->errorString()));close();return;}QLabel *statusLabel = new QLabel;statusLabel->setWordWrap(true);statusLabel->setText(tr("The server is running.\n""Run the Local Fortune Client example now."));//把各种签放入,签筒fortunes << tr("You've been leading a dog's life. Stay off the furniture.")<< tr("You've got to think about tomorrow.")<< tr("You will be surprised by a loud noise.")<< tr("You will feel hungry again in another hour.")<< tr("You might have mail.")<< tr("You cannot kill time without injuring eternity.")<< tr("Computers are not intelligent. They only think they are.");QPushButton *quitButton = new QPushButton(tr("Quit"));//自动默认按钮 设置为falsequitButton->setAutoDefault(false);connect(quitButton, &QPushButton::clicked, this, &Server::close);//每次客户端连接到服务器时,都会发出newConnection()信号。connect(server, &QLocalServer::newConnection, this, &Server::sendFortune);QHBoxLayout *buttonLayout = new QHBoxLayout;//一共三格,button在中间,两边为空。buttonLayout->addStretch(1);buttonLayout->addWidget(quitButton);buttonLayout->addStretch(1);QVBoxLayout *mainLayout = new QVBoxLayout(this);mainLayout->addWidget(statusLabel);mainLayout->addLayout(buttonLayout);setWindowTitle(QGuiApplication::applicationDisplayName());
}void Server::sendFortune()
{//const char *的高级版。//支持隐式共享 (copy-on-write)//确保以 '\0'结尾QByteArray block;//构造一个操作字节数组的数据流,QDataStream out(&block, QIODevice::WriteOnly);//如果与使用的QT版本相同可以不设置。out.setVersion(QDataStream::Qt_5_10);const int fortuneIndex = QRandomGenerator::global()->bounded(0, fortunes.size());const QString &message = fortunes.at(fortuneIndex);out << quint32(message.size());out << message;//调用nextPendingConnection()将挂起的连接接受为已连接的QLocalSocket。//该函数返回一个指向QLocalSocket的指针,用于与客户端通信。QLocalSocket *clientConnection = server->nextPendingConnection();//回收内存connect(clientConnection, &QLocalSocket::disconnected,clientConnection, &QLocalSocket::deleteLater);//block的数据与来自out数据流//将数据从以零结尾的8位字符字符串写入QLocalSocket缓冲。clientConnection->write(block);//QLocalSocket立即开始发送缓冲数据。clientConnection->flush();clientConnection->disconnectFromServer();
}
服务器main函数
#include <QApplication>#include "server.h"int main(int argc, char *argv[])
{QApplication app(argc, argv);//后面写成QApplication::tr("Local Fortune Server")也行。//QObject::tr,纯粹是为了加入翻译文件QGuiApplication::setApplicationDisplayName(Server::tr("Local Fortune Server"));Server server;server.show();return app.exec();
}
Clint 程序
Clint类定义
#ifndef CLIENT_H
#define CLIENT_H#include <QDialog>
#include <QDataStream>
#include <QLocalSocket>QT_BEGIN_NAMESPACE
class QLabel;
class QLineEdit;
class QPushButton;
QT_END_NAMESPACEclass Client : public QDialog
{Q_OBJECTpublic:explicit Client(QWidget *parent = nullptr);private slots:void requestNewFortune();void readFortune();void displayError(QLocalSocket::LocalSocketError socketError);void enableGetFortuneButton();private:QLineEdit *hostLineEdit;QPushButton *getFortuneButton;QLabel *statusLabel;QLocalSocket *socket;//接收socket中的数据//正常接收情况下in包括:blockSize和nextFortuneQDataStream in;//服务器发来的“签”的文字长度quint32 blockSize;QString currentFortune;
};#endif
Clint类实现
#include <QtWidgets>
#include <QtNetwork>#include "client.h"Client::Client(QWidget *parent): QDialog(parent),hostLineEdit(new QLineEdit("fortune")),getFortuneButton(new QPushButton(tr("Get Fortune"))),statusLabel(new QLabel(tr("This examples requires that you run the ""Local Fortune Server example as well."))),socket(new QLocalSocket(this))
{setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);QLabel *hostLabel = new QLabel(tr("&Server name:"));hostLabel->setBuddy(hostLineEdit);statusLabel->setWordWrap(true);getFortuneButton->setDefault(true);QPushButton *quitButton = new QPushButton(tr("Quit"));QDialogButtonBox *buttonBox = new QDialogButtonBox;buttonBox->addButton(getFortuneButton, QDialogButtonBox::ActionRole);buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);//从socket获取数据流in.setDevice(socket);in.setVersion(QDataStream::Qt_5_10);//本示例中下面这个connect可以忽略connect(hostLineEdit, &QLineEdit::textChanged,this, &Client::enableGetFortuneButton);connect(getFortuneButton, &QPushButton::clicked,this, &Client::requestNewFortune);connect(quitButton, &QPushButton::clicked, this, &Client::close);//每当有新的数据可从设备当前的读取通道读取时,就会发出一次readyRead信号。connect(socket, &QLocalSocket::readyRead, this, &Client::readFortune);connect(socket, QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::error),this, &Client::displayError);QGridLayout *mainLayout = new QGridLayout(this);mainLayout->addWidget(hostLabel, 0, 0);mainLayout->addWidget(hostLineEdit, 0, 1);mainLayout->addWidget(statusLabel, 2, 0, 1, 2);mainLayout->addWidget(buttonBox, 3, 0, 1, 2);setWindowTitle(QGuiApplication::applicationDisplayName());hostLineEdit->setFocus();
}void Client::requestNewFortune()
{// 本示例中,下条语句可以忽略getFortuneButton->setEnabled(false);//初始化为0blockSize = 0;//立即中止当前连接并重置套接字。socket->abort();//通过指定的关键字与Server建立连接socket->connectToServer(hostLineEdit->text());
}void Client::readFortune()
{//为blockSize赋值if (blockSize == 0) {// QDataStream将一个quint32序列化为sizeof(quint32)个字节// bytesAvailable返回可供读取的字节数。// 目前我们需要读取的blockSize,类型为quint32if (socket->bytesAvailable() < (int)sizeof(quint32))return;//从socket读取quint32,socket->bytesAvailable() 的值会相应的减少。in >> blockSize;}if (socket->bytesAvailable() < blockSize || in.atEnd())return;QString nextFortune;//从socket读取字符串,socket->bytesAvailable() 的值会相应的减少。in >> nextFortune;//确保这次抽到的签与上次不同if (nextFortune == currentFortune) {//在给定的时间间隔后调用插槽,非常方便的静态函数QTimer::singleShot(0, this, &Client::requestNewFortune);return;}currentFortune = nextFortune;statusLabel->setText(currentFortune);getFortuneButton->setEnabled(true);
}void Client::displayError(QLocalSocket::LocalSocketError socketError)
{switch (socketError) {case QLocalSocket::ServerNotFoundError:QMessageBox::information(this, tr("Local Fortune Client"),tr("The host was not found. Please make sure ""that the server is running and that the ""server name is correct."));break;case QLocalSocket::ConnectionRefusedError:QMessageBox::information(this, tr("Local Fortune Client"),tr("The connection was refused by the peer. ""Make sure the fortune server is running, ""and check that the server name ""is correct."));break;case QLocalSocket::PeerClosedError:break;default:QMessageBox::information(this, tr("Local Fortune Client"),tr("The following error occurred: %1.").arg(socket->errorString()));}getFortuneButton->setEnabled(true);
}void Client::enableGetFortuneButton()
{getFortuneButton->setEnabled(!hostLineEdit->text().isEmpty());
}
客户端 main 函数
#include <QApplication>#include "client.h"int main(int argc, char *argv[])
{QApplication app(argc, argv);QGuiApplication::setApplicationDisplayName(Client::tr("Local Fortune Client"));Client client;client.show();return app.exec();
}
QT5.14.2自带Examples:Local Fortune Server/Client相关推荐
- QT5.14.2自带Examples:Address Book
地址簿示例 地址簿示例展示了如何使用代理模式,基于同一个模型数据展示不同的视图. 这个例子提供了一个地址簿,支持将联系人按人名的头字母划分为9组: ABC, DEF, GHI, - , VW, -, ...
- QT5.14.2自带Examples:Bars
概述 本示在Widget应用程序中使用Q3DBars绘制3D柱状图,显示芬兰奥卢和赫尔辛基的平均气温(2006-2013),并通过UI操作,对显示效果进行调整.展示了以下内容: 使用Q3DBars和一 ...
- Qt5.14.2MinGW-32静态编译及压缩过程配置教程
目录 下载 下载Qt5.14.2 下载upxn 下载Python2 安装 检查配置 检查perl版本 检查python版本 静态编译 配置 编译 安装 新增静态编译环境 添加Qt Version 添加 ...
- Qt5.14.2移植到SOM-RK3399开发板上的问题解决办法
Qt5.14.2移植到SOM-RK3399开发板上的问题解决办法 1. 概述 2. 配置Qt5.9.5 2.1 mkspec配置文件 2.2 配置脚本 2.3 执行make docs时出现的错误 2. ...
- 自用笔记-Qt5.14.2开发Android环境搭建
所需软件 qt-opensource-windows-x86-5.14.2.exe android-ndk-r21e-windows-x86_64 android-sdk_r24.4.1-window ...
- 基于Qt5.14.2和mingw的Qt源码学习(三) — 元对象系统简介及moc工具是如何保存类属性和方法的
基于Qt5.14.2和mingw的Qt源码学习(三) - 元对象系统简介及moc工具是如何保存类属性和方法的 一.什么是元对象系统 1.元对象系统目的 2.实现元对象系统的关键 3.元对象系统的其他一 ...
- ubuntu安装QT5.14.2:编译项目报错、不能输入中文解决
QT安装 QT源码和SDK下载 https://download.qt.io/archive/qt/ http://www.qt.io/ http://download.qt.io/ http://w ...
- Qt5.14.2移植到SOM-RK3399开发板
Qt5.14.2移植到SOM-RK3399开发板 1. 主机开发环境 2. 安装aarch64-linux-gnu-g++交叉编译工具 3. 移植Qt 3.1 修改Qt源码中的Makefile说明文档 ...
- QT5.14.2基于PCL1.11.1显示点云(基于Windows VS2019开发环境)
文章目录 一.安装 1.1 PCL安装 1.2 QT安装 1.3 VTK编译 二.程序配置 1. 基于mscv创建QT的程序 2. 配置QT工程文件和依赖项 3. 编写点云显示的小程序 总结 一.安装 ...
最新文章
- 小学三年级上册计算机计划书,小学三年级班主任工作计划书
- Java异常有多慢?
- 用 GRUB 引导自己的操作系统
- 让数据库操作变成非阻塞的
- 科研|饶毅:科学在被淘汰的博士后引领下狂奔
- python 如何匹配一撇字符_python,yaml如何解析包含撇号的字符串
- 单例设计模式(懒汉式)(饿汉式)
- (CSCD 理工科)中文科技核心期刊汇总
- ASP.NET Web程序设计 第四章 系统对象
- 结绳计数——最原始的备忘录
- tcprewrite批量修改报文ip地址一
- html怎么自动导入数据并排序,jQuery html表格排序插件:tablesorter
- 「Android基于MQTT实现消息通知」
- os.path.dirname(os.path.realpath(__file__))函数
- python - alipay sdk 使用 及 注意点
- 2019 年第 7 周 DApp 影响力排行榜 | TokenInsight
- PHP打印调用堆栈信息,用于程序调试
- “软件”占领汽车行业,传统汽车业面临淘汰?
- 第1章 字符串练习题
- mplab哪个版本编译c语言,mplab c18编译器下载-mplab c18软件下载(正版MPLAB C18 C编译器) 3.0 完整版 - 河东下载站...