1. 程式人生 > >Qt利用QLocalSocket和QLocalServer實現IPC

Qt利用QLocalSocket和QLocalServer實現IPC

handler delet qstring OS client 但是 main his windows系統

QLocalServer提供了一種基於本地套接字的服務器,實現了接收本地socket的連接的功能。

通過調用listen()監聽特定的連接,每次與client連接上時發出newConnection()信號。

通過調用nextPendingConnection()響應一個等待中的連接請求,返回一個指針,指向用於與client建立通信的QLocalSocket。

當連接發生錯誤時,serverError() 返回錯誤的類型,通過調用errorString()可以獲取錯誤描述。

監聽過程中,serverName()可獲取當前服務器的名稱。

調用close()停止對連接請求的監聽。

雖然QLocalServer是為在事件循環中使用而設計出來的,但是在沒有事件循環時也是可以使用的。沒有事件循環時,你必須使用waitForNewConnection(),它只在以下兩種情況下解除阻塞:1)有可用的連接;2)超時。

實例1:服務器

#ifndef SERVER_H
#define SERVER_H

#include <QWidget>
#include <QObject>
#include <QLocalSocket>
#include <QLocalServer>

class CServer : public QObject
{
    Q_OBJECT

public:
    CServer() : m_server(NULL)
    {
        m_server = new QLocalServer;
        connect(m_server, SIGNAL(newConnection()), SLOT(serverNewConnectionHandler()));
    }

    
~CServer() { m_server->close(); delete m_server; } void RunServer() { qDebug() << "Run Server ok"; QLocalServer::removeServer("ServerName"); bool ok = m_server->listen("ServerName"); if (!ok) { // TODO: } }
private slots: void serverNewConnectionHandler() { qDebug() << "New Connection"; qDebug() << "listen: " << m_server->serverName(); QLocalSocket* socket = m_server->nextPendingConnection(); connect(socket, SIGNAL(readyRead()), this, SLOT(socketReadyReadHandler())); connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater())); } void socketReadyReadHandler() { QLocalSocket* socket = static_cast<QLocalSocket*>(sender()); if (socket) { QTextStream stream(socket); qDebug() << "Read Data From Client:" << stream.readAll(); QString response = "Hello Client"; socket->write(response.toUtf8()); socket->flush(); } // 返回到客戶端的void sendMessage 方法,m_socket->waitForReadyRead()之後的操作 } private: QLocalServer *m_server; }; #endif // SERVER_H #include "server.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); CServer server; server.RunServer(); return a.exec(); }

QLocalSocket繼承自QIODevice,提供了一種本地套接字,在Windows系統中其實是一種有名管道,在Unix中是一種本地套接字。

socketError()返回套接字連接錯誤類型,errorString()返回錯誤詳細描述。

也可以在沒有事件循環的情況下工作,waitForConnected(),waitForReadyRead(),waitForBytesWritten()和waitForDisconnected()用於阻塞等待事件的到來,知道事件到來或者超時。

實例2:客戶端

#ifndef CLIENT_H
#define CLIENT_H

#include <QObject>
#include <QLocalSocket>
#include <QLocalServer>

class CClient : public QObject
{
    Q_OBJECT

public:
    CClient() : m_socket(NULL)
    {
        m_socket = new QLocalSocket();

        connect(m_socket, SIGNAL(connected()), SLOT(socketConnectedHandler()));
        connect(m_socket, SIGNAL(disconnected()), SLOT(socketDisConnectedHandler()));
        connect(m_socket, SIGNAL(error(QLocalSocket::LocalSocketError)), SLOT(socketErrorHandler(QLocalSocket::LocalSocketError)));
    }

    ~CClient()
    {
        m_socket->disconnectFromServer();
        delete m_socket;
    }

public:
    void ConnectToServer(const QString &strServerName)
    {
        // serverNewConnectionHandler 成員方法將被調用
        m_socket->connectToServer(strServerName);
        if (m_socket->waitForConnected())
        {
            // TODO:
        }
    }

    void sendMessage(const QString &msg)
    {
        m_socket->write(msg.toStdString().c_str());
        m_socket->flush();

        if (!m_socket->bytesAvailable())
            m_socket->waitForReadyRead();

        QTextStream stream(m_socket);
        QString respond = stream.readAll();
        qDebug() << "Read Data From Server:" << respond;
    }

private slots:
    void socketConnectedHandler()
    {
        qDebug() << "connected.";
    }


    void socketDisConnectedHandler()
    {
        qDebug() << "disconnected.";
    }

    void socketErrorHandler(QLocalSocket::LocalSocketError error)
    {
        qWarning() << error;
    }

private:
    QLocalSocket *m_socket;

};

#endif // CLIENT_H

#include "client.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    CClient client;
    client.ConnectToServer("ServerName");

    client.sendMessage("Hellow Server");

    return a.exec();
}

Qt利用QLocalSocket和QLocalServer實現IPC