专栏首页跟Qt君学编程Qt官方示例-TCP客户端/服务器示例

Qt官方示例-TCP客户端/服务器示例

该示例演示了在本地主机上的TCP客户端和服务器是如何通讯的。

客户端

  绑定信号槽。

connect(&tcpClient, &QAbstractSocket::connected, this, &Dialog::startTransfer); /* 连接到服务器时回送消息给服务器 */
connect(&tcpClient, &QIODevice::bytesWritten,
        this, &Dialog::updateClientProgress); /* 绑定写数据到服务器的信号槽 */

  连接到服务器。

tcpClient.connectToHost(QHostAddress::LocalHost, tcpServer.serverPort());

  这里比较有意思的是,客户端连接到服务器->客户端(tcpClient)触发startTransfer槽函数->调用tcpClient.write->触发QIODevice::bytesWritten信号->触发updateClientProgress槽函数调用->就一直tcpClient.write,直到if条件不成立后后停止发送。

void Dialog::startTransfer()
{
    // called when the TCP client connected to the loopback server
    bytesToWrite = TotalBytes - int(tcpClient.write(QByteArray(PayloadSize, '@')));
    clientStatusLabel->setText(tr("Connected"));
}
void Dialog::updateClientProgress(qint64 numBytes)
{
    // called when the TCP client has written some bytes
    bytesWritten += int(numBytes);

    // only write more if not finished and when the Qt write buffer is below a certain size.
    if (bytesToWrite > 0 && tcpClient.bytesToWrite() <= 4 * PayloadSize) /* 直到if条件不成立后后停止发送 */
        bytesToWrite -= tcpClient.write(QByteArray(qMin(bytesToWrite, PayloadSize), '@'));

    clientProgressBar->setMaximum(TotalBytes);
    clientProgressBar->setValue(bytesWritten);
    clientStatusLabel->setText(tr("Sent %1MB").arg(bytesWritten / (1024 * 1024)));
}

服务端

  绑定信号槽用于新连接:

connect(&tcpServer, &QTcpServer::newConnection,
        this, &Dialog::acceptConnection);

  监听客户端连接。

!tcpServer.isListening() && !tcpServer.listen()

  服务端新连接到来:

void Dialog::acceptConnection()
{
    tcpServerConnection = tcpServer.nextPendingConnection();
    if (!tcpServerConnection) {
        serverStatusLabel->setText(tr("Error: got invalid pending connection!"));
        return;
    }

    connect(tcpServerConnection,
            &QIODevice::readyRead,
            this,
            &Dialog::updateServerProgress); /* 接受客户端数据的槽函数 */
    connect(tcpServerConnection,
            QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
            this,
            &Dialog::displayError); /* 错误反馈 */
    connect(tcpServerConnection,
            &QTcpSocket::disconnected,
            tcpServerConnection,
            &QTcpSocket::deleteLater); /* 断开反馈 */

    serverStatusLabel->setText(tr("Accepted connection"));
    tcpServer.close();
}

  接收来自客户端的数据:

void Dialog::updateServerProgress()
{
    bytesReceived += int(tcpServerConnection->bytesAvailable());
    tcpServerConnection->readAll(); /* 读数据 */

    serverProgressBar->setMaximum(TotalBytes);
    serverProgressBar->setValue(bytesReceived); /* 设置进度条 */
    serverStatusLabel->setText(tr("Received %1MB") /* 显示在界面上 */
                               .arg(bytesReceived / (1024 * 1024)));

    if (bytesReceived == TotalBytes) {
        tcpServerConnection->close();
        startButton->setEnabled(true);
#ifndef QT_NO_CURSOR
        QApplication::restoreOverrideCursor();
#endif
    }
}

关于更多

  • QtCreator软件可以找到:
  • 或在以下Qt安装目录找到:
C:\Qt\{你的Qt版本}\Examples\{你的Qt版本}\network\loopback
  • 相关链接
https://doc.qt.io/qt-5/qtnetwork-loopback-example.html

本文分享自微信公众号 - Qt君(qtjuna)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Qt TreeWidget 控件(一)

    Qt 的List Widget、Tree Widget和Table Widget属于Qt Model/View中的简便类,之前文章介绍过Qt Model/Vie...

    用户5908113
  • Qt TableWidget 控件 及自定义委托

    上次和大家分享了TreeWidget的简单使用,本次和大家分享下TableWidget的简单应用以及项目视图中的自定义委托。

    用户5908113
  • Qt官方示例-虚拟键盘使用

      该示例提供两种使用方式:一种用于桌面平台,另一种用于嵌入式平台,本例采用嵌入式平台方式显示。它们区别是前者脱离窗口应用于全局,后者依附于窗口。

    Qt君
  • Qt插件入门——使用插件扩展Qt自身

    用于编写Qt自身扩展的高级API:自定义数据库驱动程序,图像格式,文本编解码器,自定义样式等。本次的例子就是自定义样式的例子。

    用户5908113
  • Qt 2D数据可视化之QCharts

    Qt Charts 在Qt4时代就有了,不过一直以来是商业许可的。QCharts可以在社区版使用后,Qt画图再也不用需要配置第三方的qcustomplot和qw...

    用户5908113
  • Qt创建及使用动态链接库(一)

    2、显示链接DLL,调用DLL中类对象、成员函数。(通过对象即可实现类成员函数的调用)

    Sindsun
  • Qt虚拟键盘相关内容

      商业版什么时候就有? Qt虚拟键盘(1.0版本)最早出现在Qt Enterprise Embedded 5.3.0中(2014-05-22)

    Qt君
  • Python定做一个计算器,小而美哒~

    qt 设计器提供的常用控件基本都能满足开发需求,通过拖动左侧的控件,很便捷的就能搭建出如下的UI界面,比传统的手写控件代码要方便很多。

    double
  • Qt插件创建及加载

    上次我们是直接在Qt 自带的例子基础上做的修改,直接运行。我们的插件需要继承Qt 的Style插件,之后重新实现自己想要实现的部分。在主程序中直接通过QAppl...

    用户5908113
  • Qt官方示例-数字时钟

    DigitalClock继承于QLCDNumber,并实现一个槽函数showTime()用来定时更新时钟显示:

    Qt君

扫码关注云+社区

领取腾讯云代金券