概述

这是两个示例,需要配合使用。可以在本机为两个应用程序建立socket通信。

主要是对QLocalServer和QLocalSocket的使用。

QLocalServer

  1. 调用 listen(),让服务器开始监听本地套接字上指定关键字的连接。
  2. 每次客户端连接到服务器时,都会发出newConnection()信号。
  3. 调用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相关推荐

  1. QT5.14.2自带Examples:Address Book

    地址簿示例 地址簿示例展示了如何使用代理模式,基于同一个模型数据展示不同的视图. 这个例子提供了一个地址簿,支持将联系人按人名的头字母划分为9组: ABC, DEF, GHI, - , VW, -, ...

  2. QT5.14.2自带Examples:Bars

    概述 本示在Widget应用程序中使用Q3DBars绘制3D柱状图,显示芬兰奥卢和赫尔辛基的平均气温(2006-2013),并通过UI操作,对显示效果进行调整.展示了以下内容: 使用Q3DBars和一 ...

  3. Qt5.14.2MinGW-32静态编译及压缩过程配置教程

    目录 下载 下载Qt5.14.2 下载upxn 下载Python2 安装 检查配置 检查perl版本 检查python版本 静态编译 配置 编译 安装 新增静态编译环境 添加Qt Version 添加 ...

  4. 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. ...

  5. 自用笔记-Qt5.14.2开发Android环境搭建

    所需软件 qt-opensource-windows-x86-5.14.2.exe android-ndk-r21e-windows-x86_64 android-sdk_r24.4.1-window ...

  6. 基于Qt5.14.2和mingw的Qt源码学习(三) — 元对象系统简介及moc工具是如何保存类属性和方法的

    基于Qt5.14.2和mingw的Qt源码学习(三) - 元对象系统简介及moc工具是如何保存类属性和方法的 一.什么是元对象系统 1.元对象系统目的 2.实现元对象系统的关键 3.元对象系统的其他一 ...

  7. ubuntu安装QT5.14.2:编译项目报错、不能输入中文解决

    QT安装 QT源码和SDK下载 https://download.qt.io/archive/qt/ http://www.qt.io/ http://download.qt.io/ http://w ...

  8. Qt5.14.2移植到SOM-RK3399开发板

    Qt5.14.2移植到SOM-RK3399开发板 1. 主机开发环境 2. 安装aarch64-linux-gnu-g++交叉编译工具 3. 移植Qt 3.1 修改Qt源码中的Makefile说明文档 ...

  9. QT5.14.2基于PCL1.11.1显示点云(基于Windows VS2019开发环境)

    文章目录 一.安装 1.1 PCL安装 1.2 QT安装 1.3 VTK编译 二.程序配置 1. 基于mscv创建QT的程序 2. 配置QT工程文件和依赖项 3. 编写点云显示的小程序 总结 一.安装 ...

最新文章

  1. 小学三年级上册计算机计划书,小学三年级班主任工作计划书
  2. Java异常有多慢?
  3. 用 GRUB 引导自己的操作系统
  4. 让数据库操作变成非阻塞的
  5. 科研|饶毅:科学在被淘汰的博士后引领下狂奔
  6. python 如何匹配一撇字符_python,yaml如何解析包含撇号的字符串
  7. 单例设计模式(懒汉式)(饿汉式)
  8. (CSCD 理工科)中文科技核心期刊汇总
  9. ASP.NET Web程序设计 第四章 系统对象
  10. 结绳计数——最原始的备忘录
  11. tcprewrite批量修改报文ip地址一
  12. html怎么自动导入数据并排序,jQuery html表格排序插件:tablesorter
  13. 「Android基于MQTT实现消息通知」
  14. os.path.dirname(os.path.realpath(__file__))函数
  15. python - alipay sdk 使用 及 注意点
  16. 2019 年第 7 周 DApp 影响力排行榜 | TokenInsight
  17. PHP打印调用堆栈信息,用于程序调试
  18. “软件”占领汽车行业,传统汽车业面临淘汰?
  19. 第1章 字符串练习题
  20. mplab哪个版本编译c语言,mplab c18编译器下载-mplab c18软件下载(正版MPLAB C18 C编译器) 3.0 完整版 - 河东下载站...

热门文章

  1. 解锁新姿势:FairyGUI在Unity中遇见的问题-第三弹
  2. Java实现冒泡排序和选择排序
  3. 电脑如何连接隐藏的无线WiFi信号呢?
  4. linux ubunto全键盘 手机,全键盘设计,XDA打造运行LineageOS和Ubuntu Touch OS的手机
  5. 树莓派:虚拟键盘软件
  6. 【二分 数学 0/1分数规划】JZOJ_4230 淬炼神体
  7. CentOS7 Systemtap 安装
  8. bootstrap浮窗
  9. java8 中的 Collectors 全解析
  10. 配置实验室服务器环境(记录一些坑)