• QLocalServer和QLocalSocket单进程和进程通信


    QLocalServer

    继承自QObject。

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

    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端:
    
    ////////////////////////////////////////////////////////////////////////////////
    // 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发送一个随机数:
    用于测试的客户端代码, 每一秒向server发送一个随机数:
    
    #include <QLocalSocket>
    #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()) + "
    TTTTTTTTTT" + "
    XXXXXXXX";
                ts.flush();
                ls.waitForBytesWritten();
                sleep(1);
            }
        }
        return 0;
    }
  • 相关阅读:
    Vue-CLI
    Vue生命周期函数
    构建之法阅读笔记之四
    大二下个人总结
    个人加分项
    对老师的建议
    学习进度条 第九十一-第一百零五天 vue+uniapp app开发学习笔记
    第15周作业
    二进制安装mysql 5.7.31 启动报错/etc/init.d/mysqld: line 239: my_print_defaults: command not found
    获取最小数字
  • 原文地址:https://www.cnblogs.com/whwywzhj/p/10071600.html
Copyright © 2020-2023  润新知