您的代碼存在問題,因爲您使用while循環阻止事件循環。所以,你的問題的解決方案是從stdin異步讀取。在Linux上(在Mac上,我猜),您可以使用QSocketNotifier
來通知數據何時到達stdin,並手動讀取),如各種互聯網源。
由於我使用的是Windows,我建議你做這樣(應在所有平臺上工作):
- 打開線程從標準
- 一旦你得到一些讀取數據數據(可能是行?),您可以使用Qt信號插槽機制將數據傳遞到主線程進行處理,而不會阻塞事件循環。
所以,這是僞代碼。 MainAppClass應該是您現有的服務器類,只需編輯構造函數即可創建新線程,並添加新插槽來處理數據。
class Reader: public QThread
{
Q_OBJECT
public:
Reader(QObject * parent = 0): QThread(parent){}
void run(void)
{
forever{
std::string data;
std::getline (std::cin, data);
if(data == "exit")
{
emit exitServer();
return;
}
emit dataReady(QString::fromStdString(data));
}
}
signals:
void dataReady(QString data);
void exitServer();
};
class MainAppClass: public QObject
{
Q_OBJECT
public:
MainAppClass()
{
Reader * tr = new Reader(this);
connect(tr, SIGNAL(dataReady(QString)), this, SLOT(processData(QString)));
connect(tr, SIGNAL(exitServer()), this, SLOT(exitServer()));
tr->start();
}
public slots:
void processData(QString data)
{
std::cout << "Command: " << data.toStdString() << std::endl;
}
void exitServer()
{
std::cout << "Exiting..." << std::endl;
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainAppClass myapp; //your server
app.exec();
return 0;
}
因爲我寫了簡單的指導如何使用與QTcpSocket,這裏是短暫
當你的客戶QTcpSocket
,readyRead()
信號連接到某些插槽,並從sender()
對象讀取數據。您不需要在構造函數中讀取任何內容。
對於閱讀,您可以使用標準QIODevice
函數。
注:這是僞代碼,您可能需要改變一些東西(檢查讀取流的狀態,保存指針插座在一些名單,訂閱disconnected()
信號,調用構造函數listen()
,檢查如果QTcpServer
正在監聽等)。
所以,你需要在你的類插槽onReadyRead()
這將有以下代碼:
void Server::readyReadSlot()
{
QTcpSocket *client = (QTcpSocket*)sender(); // get socket which emited the signal
while(client->canReadLine()) // read all lines!
// If there is not any lines received (you may not always receive
// whole line as TCP is stream based protocol),
// you will not leave data in the buffer for later processing.
{
QString line = client->readLine();
processLine(line); // or emit new signal if you like
}
}
裏面你需要readyRead()
信號與插槽連接newConnection()
。
void Server::newConnection()
{
QTcpSocket *clientSocket = server->nextPendingConnection();
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readyReadSlot()));
}
我很困惑你的答案。根據我對你所說的話的理解,這不是解決我的問題的方法。但我可能會誤解你。 – Mitch
不,我誤解了你 - 我正在閱讀我的手機!對不起,我現在編輯我的答案。 –
@Mitch,請參閱我編輯的第一部分。 –