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; }
坚持就是胜利