gpt4 book ai didi

c++ - Qt C++ 控制台服务器,等待套接字连接并同时接受输入?

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:52:01 24 4
gpt4 key购买 nike

我正在将服务器编写为 Qt 控制台应用程序。我将服务器设置为等待套接字连接,但我还需要允许用户向服务器输入命令以管理它。两者都是独立工作的。然而,我遇到的问题是,当我在 while 循环中接受和处理输入命令时,服务器不接受连接。

我有一个 Socket 类,在它的构造函数中,我有:

connect(server,SIGNAL(newConnection()),this, SLOT(newConnection()));

在构造函数的正下方,我调用了一个具有更深入版本的函数来从用户那里获取命令:

QTextStream qin(stdin, QIODevice::ReadOnly);
QString usrCmd;

while(usrCmd != "exit" && usrCmd != "EXIT") {
//Get command input and process here
}

在 newConnection() 中,我只是接受下一个连接,然后使用套接字。

QTcpSocket *serverSocket = server->nextPendingConnection();

我怎样才能使套接字可以同时等待连接等待用户输入的命令?

最佳答案

您的代码有问题是因为您使用 while 循环阻止了事件循环。因此,您的问题的解决方案是异步读取标准输入。在 Linux 上(我想在 Mac 上),您可以使用 QSocketNotifier 通知数据何时到达标准输入,并手动读取),根据各种互联网资源。

由于我使用的是 Windows,因此我建议您以这种方式进行操作(应该适用于所有平台):

  1. 开启从stdin读取数据的线程
  2. 一旦获得一些数据(也许是行?),您就可以使用 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()信号连接到某个slot,并从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
}
}

newConnection() 中,您需要将 readyRead() 信号与您的插槽连接。

void Server::newConnection()
{
QTcpSocket *clientSocket = server->nextPendingConnection();
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readyReadSlot()));
}

关于c++ - Qt C++ 控制台服务器,等待套接字连接并同时接受输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14697168/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com