描述:
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 加以修改和實現