Qt 之进程间通信(TCP/IP)

Qt 之进程间通信(TCP/IP)

简述

可以通过Qt提供的IPC使用TCP/IP,使用QtNetwork模块即可实现,TCP/IP在实现应用程序和进程内部通信或与远程进程间的通信方面非常有用。

QtNetwork模块提供的类能够创建基于TCP/IP的客户端与服务端应用程序。为实现底层的网络访问,可以使用QTcpSocket、QTcpServer和QUdpSocket,并提供底层网络类。还提供了使用常规协议实现网络操作的QNetworkRequest、QNetworkReply、QNetworkAccessManager。

| 版权声明:一去、二三里,未经博主允许不得转载。

QtNetwork

作为使用IPC的方法,TCP/IP可以使用多种类进行进程内部和外部的通信。

QtNetwork模块提供的类:

说明
QLocalServer基于服务器的本地套接字的类
QLocalSocket支持本地套接字的类
QNetworkAccessManager处理从网络首发收据响应的类
QSocketNotifier监控从网络通知消息的类
QSsl在所有网络通信上用于SSL认证的类
QSslSocket支持通过客户端和服务器端加密的套接字的类
QTcpServer基于TCP的服务器端类
QTcpSocketTCP套接字
QUdpSocketUDP套接字

除表中所示,Qt提供的QtNetwork模块还支持多种协议。如果需要实现内部进程间的通信,建议使用QLocalSocket类。

下面我们来看一个示例,可以在Creator自带的示例中查找QLocalSocket或Local Fortune。

Server

首先,启动Server,这是必然的,服务端不开启,客户端怎么连接得上呢?

server = new QLocalServer(this);

// 告诉服务器监听传入连接的名字。如果服务器当前正在监听,那么将返回false。监听成功返回true,否则为false
if (!server->listen("fortune")) {
    QMessageBox::critical(this, tr("Fortune Server"),
                        tr("Unable to start the server: %1.")
                        .arg(server->errorString()));
    close();
    return;
}

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.");

// 有新客户端进行连接时,发送数据
connect(server, SIGNAL(newConnection()), this, SLOT(sendFortune()));

// 发送数据
void Server::sendFortune()
{
    // 从fortunes中随机取出一段字符串然后进行写入。
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_0);
    out << (quint16)0;
    out << fortunes.at(qrand() % fortunes.size());
    out.device()->seek(0);
    out << (quint16)(block.size() - sizeof(quint16));

    // nextPendingConnection()可以返回下一个挂起的连接作为一个连接的QLocalSocket对象。
    QLocalSocket *clientConnection = server->nextPendingConnection();
    connect(clientConnection, SIGNAL(disconnected()),
            clientConnection, SLOT(deleteLater()));

    clientConnection->write(block);
    clientConnection->flush();
    clientConnection->disconnectFromServer();
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

socket被当做server的孩子创建,这意味着,当QLocalServer对象被销毁时它也会被自动删除。这明显是一个删除对象的好主意,使用完成以后,避免了内存的浪费。

Client

启动客户端,连接到对应的服务器,如果连接不上,则进行错误处理。

socket = new QLocalSocket(this);

connect(getFortuneButton, SIGNAL(clicked()),
        this, SLOT(requestNewFortune()));
connect(socket, SIGNAL(readyRead()), this, SLOT(readFortune()));
connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)),
        this, SLOT(displayError(QLocalSocket::LocalSocketError)));

// 连接到服务器,abort()断开当前连接,重置socket。
void Client::requestNewFortune()
{
    getFortuneButton->setEnabled(false);
    blockSize = 0;
    socket->abort();
    socket->connectToServer(hostLineEdit->text());
}

// 读取服务器端发送的数据
void Client::readFortune()
{
    // 读取接收到的数据
    QDataStream in(socket);
    in.setVersion(QDataStream::Qt_4_0);

    if (blockSize == 0) {
        if (socket->bytesAvailable() < (int)sizeof(quint16))
            return;
        in >> blockSize;
    }

    if (in.atEnd())
        return;

    QString nextFortune;
    in >> nextFortune;

    // 如果当前的数据和收到的数据相同,则重新请求一次,因为是随机的字符串,所以肯定不会每次都相同。
    if (nextFortune == currentFortune) {
        QTimer::singleShot(0, this, SLOT(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("Fortune Client"),
                                 tr("The host was not found. Please check the "
                                    "host name and port settings."));
        break;
    case QLocalSocket::ConnectionRefusedError:
        QMessageBox::information(this, tr("Fortune Client"),
                                 tr("The connection was refused by the peer. "
                                    "Make sure the fortune server is running, "
                                    "and check that the host name and port "
                                    "settings are correct."));
        break;
    case QLocalSocket::PeerClosedError:
        break;
    default:
        QMessageBox::information(this, tr("Fortune Client"),
                                 tr("The following error occurred: %1.")
                                 .arg(socket->errorString()));
    }

    getFortuneButton->setEnabled(true);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

更多参考

  •                     <li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#csdnc-thumbsup"></use>
                        </svg><span class="name">点赞</span>
                        <span class="count">5</span>
                        </a></li>
                        <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;popu_824&quot;}"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-csdnc-Collection-G"></use>
                        </svg><span class="name">收藏</span></a></li>
                        <li class="tool-item tool-active is-share"><a href="javascript:;"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-csdnc-fenxiang"></use>
                        </svg>分享</a></li>
                        <!--打赏开始-->
                                                <!--打赏结束-->
                                                <li class="tool-item tool-more">
                            <a>
                            <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
                            </a>
                            <ul class="more-box">
                                <li class="item"><a class="article-report">文章举报</a></li>
                            </ul>
                        </li>
                                            </ul>
                </div>
                            </div>
            <div class="person-messagebox">
                <div class="left-message"><a href="https://blog.csdn.net/u011012932">
                    <img src="https://profile.csdnimg.cn/6/9/A/3_u011012932" class="avatar_pic" username="u011012932">
                                            <img src="https://g.csdnimg.cn/static/user-reg-year/1x/7.png" class="user-years">
                                    </a></div>
                <div class="middle-message">
                                        <div class="title"><span class="tit"><a href="https://blog.csdn.net/u011012932" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}" target="_blank">一去丶二三里</a></span>
                                                    <span class="flag expert">
                                <a href="https://blog.csdn.net/home/help.html#classicfication" target="_blank">
                                    <svg class="icon" aria-hidden="true">
                                        <use xlink:href="#csdnc-blogexpert"></use>
                                    </svg>
                                    博客专家
                                </a>
                            </span>
                                            </div>
                    <div class="text"><span>发布了414 篇原创文章</span> · <span>获赞 3930</span> · <span>访问量 571万+</span></div>
                </div>
                                <div class="right-message">
                                            <a href="https://bbs.csdn.net/forums/p-u011012932" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-messageboard">他的留言板
                        </a>
                                                            <a class="btn btn-sm attented bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}">已关注</a>
                                    </div>
                            </div>
                    </div>
    </article>
    
        <div class="hide-article-box hide-article-pos text-center">
        <a class="btn-readmore" data-report-view="{&quot;mod&quot;:&quot;popu_376&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/liang19890820/article/details/50633819&quot;,&quot;strategy&quot;:&quot;readmore&quot;}" data-report-click="{&quot;mod&quot;:&quot;popu_376&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/liang19890820/article/details/50633819&quot;,&quot;strategy&quot;:&quot;readmore&quot;}">
            展开阅读全文
            <svg class="icon chevrondown" aria-hidden="true">
                <use xlink:href="#csdnc-chevrondown"></use>
            </svg>
        </a>
    </div>
<script>
$("#blog_detail_zk_collection").click(function(){
    window.csdn.articleCollection()
})
还能输入1000个字符
<div class="comment-list-container">
	<a id="comments"></a>
	<div class="comment-list-box" style="max-height: none;"><ul class="comment-list"><li class="comment-line-box d-flex" data-commentid="6046678" data-replyname="res518357">      <a target="_blank" href="https://me.csdn.net/res518357"><img src="https://profile.csdnimg.cn/1/D/2/3_res518357" username="res518357" alt="res518357" class="avatar"></a>        <div class="right-box ">          <div class="new-info-box clearfix">            <a target="_blank" href="https://me.csdn.net/res518357"><span class="name ">cdn_yiqian</span></a><span class="date" title="2016-05-23 22:48:13">3年前</span><span class="floor-num">#2楼</span><span class="new-comment">怎么实现外网和内网通信呢?楼主</span><span class="new-opt-box"><a class="btn btn-link-blue btn-report" data-type="report">举报</a><a class="btn btn-link-blue btn-reply" data-type="reply">回复</a><a class="btn btn-link-blue btn-read-reply" data-type="readreply">查看回复(1)</a></span></div><div class="comment-like " data-commentid="6046678"><svg t="1569296798904" class="icon " viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5522" width="200" height="200"><path d="M726.016 906.666667h-348.586667a118.016 118.016 0 0 1-116.992-107.904l-29.013333-362.666667A117.589333 117.589333 0 0 1 348.458667 309.333333H384c126.549333 0 160-104.661333 160-160 0-51.413333 39.296-88.704 93.397333-88.704 36.906667 0 71.68 18.389333 92.928 49.194667 26.88 39.04 43.178667 111.658667 12.714667 199.509333h95.530667a117.418667 117.418667 0 0 1 115.797333 136.106667l-49.28 308.522667a180.608 180.608 0 0 1-179.072 152.704zM348.458667 373.333333l-4.48 0.170667a53.461333 53.461333 0 0 0-48.768 57.472l29.013333 362.666667c2.218667 27.52 25.6 49.024 53.205333 49.024h348.544a116.949333 116.949333 0 0 0 115.925334-98.816l49.322666-308.736a53.418667 53.418667 0 0 0-52.650666-61.781334h-144.085334a32 32 0 0 1-28.458666-46.634666c45.909333-89.130667 28.885333-155.434667 11.562666-180.522667a48.981333 48.981333 0 0 0-40.192-21.504c-6.912 0-29.397333 1.792-29.397333 24.704 0 111.317333-76.928 224-224 224h-35.541333zM170.624 906.666667a32.042667 32.042667 0 0 1-31.872-29.44l-42.666667-533.333334a32.042667 32.042667 0 0 1 29.354667-34.474666c17.066667-1.408 33.024 11.733333 34.432 29.354666l42.666667 533.333334a32.042667 32.042667 0 0 1-31.914667 34.56z" p-id="5523"></path></svg><span></span></div></div></li><li class="replay-box"><ul class="comment-list"><li class="comment-line-box d-flex" data-commentid="6047257" data-replyname="u011012932">      <a target="_blank" href="https://me.csdn.net/u011012932"><img src="https://profile.csdnimg.cn/6/9/A/3_u011012932" username="u011012932" alt="u011012932" class="avatar"></a>        <div class="right-box reply-box">          <div class="new-info-box clearfix">            <a target="_blank" href="https://me.csdn.net/u011012932"><span class="name mr-8">一去丶二三里</span></a><span class="text">回复</span>  <span class="nick-name">cdn_yiqian</span><span class="date" title="2016-05-24 14:28:24">3年前</span><span class="text"></span><span class="new-comment">通过代理来设置</span><span class="new-opt-box"><a class="btn btn-link-blue btn-report" data-type="report">举报</a><a class="btn btn-link-blue btn-reply" data-type="reply">回复</a></span></div><div class="comment-like " data-commentid="6047257"><svg t="1569296798904" class="icon " viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5522" width="200" height="200"><path d="M726.016 906.666667h-348.586667a118.016 118.016 0 0 1-116.992-107.904l-29.013333-362.666667A117.589333 117.589333 0 0 1 348.458667 309.333333H384c126.549333 0 160-104.661333 160-160 0-51.413333 39.296-88.704 93.397333-88.704 36.906667 0 71.68 18.389333 92.928 49.194667 26.88 39.04 43.178667 111.658667 12.714667 199.509333h95.530667a117.418667 117.418667 0 0 1 115.797333 136.106667l-49.28 308.522667a180.608 180.608 0 0 1-179.072 152.704zM348.458667 373.333333l-4.48 0.170667a53.461333 53.461333 0 0 0-48.768 57.472l29.013333 362.666667c2.218667 27.52 25.6 49.024 53.205333 49.024h348.544a116.949333 116.949333 0 0 0 115.925334-98.816l49.322666-308.736a53.418667 53.418667 0 0 0-52.650666-61.781334h-144.085334a32 32 0 0 1-28.458666-46.634666c45.909333-89.130667 28.885333-155.434667 11.562666-180.522667a48.981333 48.981333 0 0 0-40.192-21.504c-6.912 0-29.397333 1.792-29.397333 24.704 0 111.317333-76.928 224-224 224h-35.541333zM170.624 906.666667a32.042667 32.042667 0 0 1-31.872-29.44l-42.666667-533.333334a32.042667 32.042667 0 0 1 29.354667-34.474666c17.066667-1.408 33.024 11.733333 34.432 29.354666l42.666667 533.333334a32.042667 32.042667 0 0 1-31.914667 34.56z" p-id="5523"></path></svg><span></span></div></div></li></ul></li></ul><ul class="comment-list"><li class="comment-line-box d-flex" data-commentid="5927760" data-replyname="hezf_hero">      <a target="_blank" href="https://me.csdn.net/hezf_hero"><img src="https://profile.csdnimg.cn/D/4/2/3_hezf_hero" username="hezf_hero" alt="hezf_hero" class="avatar"></a>        <div class="right-box ">          <div class="new-info-box clearfix">            <a target="_blank" href="https://me.csdn.net/hezf_hero"><span class="name ">hezf_hero</span></a><span class="date" title="2016-03-11 08:41:50">3年前</span><span class="floor-num">#1楼</span><span class="new-comment">请问博主

QT的CS架构还是基于TCP/IP的靠谱吧?
一般的通信可以使用json-rpc远程调用,但是传资源的时候还得靠基本的TCP链接
那么问题来了
我想传一条完整的信息,包括简单的标题,文字描述,还有图片和一小段视频资源
这样应该怎么处理呢?单独传的话都是没有问题的
但是不知道怎么把它们连在一起

最后感谢博主,才发现这个系列,造福人类啊,在群里公告可以宣传下举报回复查看回复(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值