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()) + "\nTTTTTTTTTT" + "\nXXXXXXXX";
            ts.flush();
            ls.waitForBytesWritten();
            sleep(1);
        }
    }
    return 0;
}

 

posted @ 2018-12-05 16:14  wjbooks  阅读(2506)  评论(0编辑  收藏  举报