【问题标题】:Manage concurrent requests from single client using QTcpServer/QTcpSocket使用 QTcpServer/QTcpSocket 管理来自单个客户端的并发请求
【发布时间】:2018-08-07 00:53:44
【问题描述】:

我需要创建一个 TCP 客户端/服务器应用程序,其中(单个)客户端根据用户命令向服务器发送请求,而且还需要定期发送“看门狗”消息。看门狗消息需要从服务器立即处理;如果当看门狗请求到达时服务器仍在处理先前的“重”请求,它必须能够尽快回答新请求(阻止当前处理,回答看门狗请求(只是回显),继续处理)。

获得这种行为的最佳方法是什么?

我已经阅读了几个主题,但我不确定要遵循哪一个主题才能获得所需的行为。

到目前为止的故事

我有一个(单个)客户端/服务器 Qt 应用程序。我正在使用信号/插槽异步管理通信。客户端发送请求,服务器在收到数据时向应用程序发出信号,应用程序解析请求并做一些事情,然后 ack/nack 请求。假设客户端正在发送单个请求,在发送新请求之前等待 ack/nack。

到目前为止,一切都完美无缺。

现在我必须添加一个“看门狗”命令,该命令将由客户端定期发送(例如使用 QTimer),打破“单一消息”假设。由于信号/插槽 Qt 管理,认为它可以开箱即用;事实证明并不是那么简单......

发生的情况是,当用户发送“繁重的处理请求”(可以简化为在回复 ack 之前休眠 5 秒)时,客户端也会发送周期性的看门狗消息(例如,每秒),但是在服务器端,只有在处理终止时,我才会收到一个新的 dataReady() 信号。

我通过 moveToThread(无法使用它;仍然收到“来自不同线程发出的套接字”错误)或通过子类化 QTread(工作,但仍然阻塞)阅读了有关线程化套接字的信息。

我不会提供代码 sn-p(目前),因为它很长,即使对于一个最小的示例也是如此。首先,我会问你什么是最好的方法。

【问题讨论】:

    标签: multithreading qt sockets


    【解决方案1】:

    如果您的服务器是单线程的并且您在其插槽中处理大量请求,readyRead() 信号在收到时会在消息循环中排队(因为一次只能处理一个插槽)并且直到当前插槽才会被处理已完成,因此服务器无法同时响应ping。您可以 1)在处理繁重的请求时调用 qApp->processEvents(); 或 2)将处理移动到另一个线程(使用工作线程)。我会使用第二个选项,因为这样代码更具可读性(在我看来)。根据经验:如果您希望某些东西具有响应性(gui、服务器等),请将重物移开。这是第二种方法的粗略实现:https://github.com/mugiseyebrows/concurrent-requests

    【讨论】:

    • 如果我做对了,在您的 (2) 选项中,您说我必须将单个 readReady() 处理移动到新线程,而不是实际的套接字(通过 moveToThread())做过。有道理。
    猜你喜欢
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 2011-09-27
    • 1970-01-01
    相关资源
    最近更新 更多