QLocalServer和QLocalSocket单进程和进程通信

本文详细介绍了QLocalServer的使用方法,包括如何创建一个基于本地套接字的服务端,如何监听和处理连接请求,并通过示例代码展示了从初始化到读取数据的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述:
QLocalServer 继承自QObject。QLocalServer提供了一个基于本地套接字(socket)的服务端(server)。它可以接受来自本地socket的连接。server通过调用listen(),监听特定的连接。newConnection()是在每次server与client连接上时所发出的信号。nextPending- Connection()将等待中的连接当作一个已连接上的QLocalSocket。返回值是指向QLocalSocket的指针,这个QLocalSocket可以与client建立通信。当发生错误时,serverError() 返回错误的类型,调用errorString()可以获取对错误的描述。 在监听过程中,通过 server- Name()可以获取当前server监听的名称。close()使QLocalServer停止对连接请求的监听。虽然QLocalServer是为在事件循环中使用而设计出来的,但是在没有事件循环时也是可以使用的。
注意:没有事件循环时,你必须使用waitForNewConnection(),它只在以下两种情况下解除阻塞:1)有可用的连接;2)超时。

在Qt中,提供了多种IPC方法,QLocalServer和QLocalSocket算是其一。它的表现看起来好像和Socket搭上点边,实际它的底层是windows的name pipe(有名管道(QLocalSocket))。它是支持全双工通信的。QLocalServer主要用来监听某个管道。建立一个监听可以这样做:
(如下)

建立实例:
1. 建立一个QLocalServer实例 m_server
2. 进行listen :

m_server->listen("servername")

3.当有连接到来时,QLocalServer会发送netConnection()信号,所以进行信号连接, 在init()函数中:

connect(m_server, SIGNAL(newConnection()), this, SLOT(newConnection()));

4.在newConnection()函数中取得连接客户端的QLocalSocket

QLocalSocket *newsocket = m_server->nextPendingConnection();

5.当QLocalSocket可以读数据时它会发送readyRead()信号,所以对newsocket进行信号连接, 在newConnection()函数中:

   connect(newsocket, SIGNAL(readyRead()), this, SLOT(readyRead()));

6.在readyRead()函数中读取数据:
// 取得是哪个localsocket可以读数据了

     QLocalSocket *local = static_cast<QLocalSocket *>(sender()); 
        if (!local) return;
        QTextStream in(local);
        QString     readMsg;
        // 读出数据
        readMsg = in.readAll();

全部代码, server端:
// server.h

#ifndef SERVER_H
#define SERVER_H
#include <QLocalServer>
#include <QLocalSocket>
class Server : public QObject
{
    Q_OBJECT
public:
    Server()
    {
        m_server = 0;
    } 
    ~Server()
    {
        if (m_server) {
            delete m_server;
        }
    }
    int init(const QString & servername)
    {
        // 如果已经有一个实例在运行了就返回0
        if (isServerRun(servername)) {
            return 0;
        }
        m_server = new QLocalServer;
        // 先移除原来存在的,如果不移除那么如果
        // servername已经存在就会listen失败
        QLocalServer::removeServer(servername);
        // 进行监听
        m_server->listen(servername);
        connect(m_server, SIGNAL(newConnection()), this, SLOT(newConnection()));
        return 1;
    }
private slots:
    // 有新的连接来了
    void newConnection()
    {
        QLocalSocket *newsocket = m_server->nextPendingConnection(); 
        connect(newsocket, SIGNAL(readyRead()), this, SLOT(readyRead()));
    }  
    // 可以读数据了
    void readyRead()
    {
        // 取得是哪个localsocket可以读数据了
        QLocalSocket *local = static_cast<QLocalSocket *>(sender()); 
        if (!local) return;
        QTextStream in(local);
        QString     readMsg;
        readMsg = in.readAll(); // 读出数据
        emit newMessage(readMsg);// 发送收到数据信号
    }
private:
    // 判断是否有一个同名的服务器在运行
    int isServerRun(const QString & servername)
    {
        // 用一个localsocket去连一下,如果能连上就说明
        // 有一个在运行了
        QLocalSocket ls;
        ls.connectToServer(servername);
        if (ls.waitForConnected(1000)){ 
            ls.disconnectFromServer();// 说明已经在运行了
            ls.close();
            return 1;
        }
        return 0;
    }
signals:
    void newMessage(const QString &msg);
private:
    QLocalServer *m_server;
};
#endif // SERVER_H

///////////////////////////////////////////////////////////////////////
/// main.cpp
///////////////////////////////////////////////////////////////////////

#include <QApplication>
#include <QLabel>
#include <QMessageBox>
#include "server.h"
int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    QLabel       text("teststts");
    Server       s;
    if (!s.init("localserver-test")){
        // 初使化失败, 说明已经有一个在运行了
        QMessageBox::information(&text, "info", "There is already exist one!"); 
        return 1;
    }
    QObject::connect(&s, SIGNAL(newMessage(const QString &)),&text, SLOT(setText(const QString &)));
    text.show();
    return app.exec();
}

用于测试的客户端代码, 每一秒向server发送一个随机数: 
 #include <QLoacalSocket>
 #include <stdlib.h>
 #include <unistd.h>
int main(int argc, char **argv)
{
    QLocalSocket ls;
    ls.connectToServer("localserver-test");
    srandom(1000);

    if (ls.waitForConnected()){
        while (1){
            QTextStream ts(&ls);
            ts << QString::number(random()) + "\nTTTTTTTTTT" + "\nXXXXXXXX";
            ts.flush();
            ls.waitForBytesWritten();
            sleep(1);
        }
    }
    return 0;
}

先运行server程序, 然后运行测试用的客户端…

本来参照 http://www.aiuxian.com/article/p-3105197.html
http://blog.chinaunix.net/uid-20718335-id-1993073.html 加以修改和实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值