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
m_server->listen("servername")
connect(m_server, SIGNAL(newConnection()), this, SLOT(newConnection()));
QLocalSocket *newsocket = m_server->nextPendingConnection();
// 取得是哪個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; }