带有 python 扭曲服务器的 Qt C++ tcp 客户端

Posted

技术标签:

【中文标题】带有 python 扭曲服务器的 Qt C++ tcp 客户端【英文标题】:Qt C++ tcp client with python twisted server 【发布时间】:2010-10-24 01:43:20 【问题描述】:

我正在尝试将一个非常基本的扭曲“hello world”服务器与一个基本的 Qt tcp 客户端连接。

客户端使用这些信号:

connect(&socket, SIGNAL(connected()), this, SLOT(startTransfer()));
connect(&socket, SIGNAL(readyRead()), this, SLOT(readServer()));

然后 readServer() 看起来像这样:

ui->resultLabel->setText("Reading..");
QDataStream in(&socket);
//in.setVersion(QT_4_0);

if (blockSize == 0) 
    if (socket.bytesAvailable() < (int)sizeof(quint16))
        return;

    in >> blockSize;


if (socket.bytesAvailable() < blockSize)
    return;

QString theResult;
in >> theResult;
qDebug() << in;
qDebug() << theResult;
ui->resultLabel->setText(theResult);

我用于测试的服务器只是从 twisted 的文档中摘取的一个示例

from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor

### Protocol Implementation

# This is just about the simplest possible protocol
class Echo(Protocol):
    def dataReceived(self, data):
        """
        As soon as any data is received, write it back.
        """
        self.transport.write(data)


def main():
    f = Factory()
    f.protocol = Echo
    reactor.listenTCP(8000, f)
    reactor.run()

if __name__ == '__main__':
    main()

readServer() 被调用得很好,但它似乎从未收集任何数据。我在某处读到这可能与 QDataStream 的

我承认我对 C++ 或 Qt 不是很精通,但该项目的想法是编写一个客户端来与现有的扭曲服务器一起工作,所以虽然可以更改客户端,但我别无选择让它与这个服务器一起工作。

提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

问题原来是 QDataStream,它显然不仅仅是它正在读取的数据的一点特殊性。

谢天谢地,我发现 QDataStream::readRawData 更喜欢由 python 发送的数据(进一步我发现这与 twisted 无关,而是 python 套接字实现本身。)最终代码如下所示:

//use socket to construct a QDataStream object, like before
QDataStream in(&socket); 
//in.setVersion(QDataStream::Qt_4_0);
char buffer[1024] = 0;
//readRawData takes a char to dump to and the length, 
//so I'm sure there is a better way to do this. It worked for my example.
in.readRawData(buffer, socket.bytesAvailable()); 
QString result;
result = buffer;
ui->resultLabel->setText(result);

【讨论】:

【参考方案2】:

了解 TCP 的重要一点是它不是特定大小的消息(或“块”)的传输。它是字节流的传输。当你写这样的东西时:

if (socket.bytesAvailable() < (int)sizeof(quint16))
    return;

那么你最好在某个地方有一个循环再次调用这段代码,因为不能保证你第一次得到通过这个检查所需的所有字节。

您没有共享任何负责将数据发送到回显服务器的代码,因此不可能真正知道为什么您的 Qt 客户端没有获得您期望的数据,但鉴于上述情况,我不会如果它涉及不完整数据的不正确缓冲,请不要感到惊讶。

确保如果您因为没有足够的数据而决定不从套接字读取数据,请稍后在可能有更多数据到达后再次尝试从该套接字读取。做到这一点的一个好方法是实际上总是将数据读入应用程序缓冲区,以便您可以使用 select() 或 epoll() 或当套接字上有更多可用数据时告诉您什么。然后对应用缓冲区进行操作即可。

【讨论】:

谢谢,我已经阅读了很多关于此的内容,可能需要阅读更多内容。正如我所说,这是我的第一次尝试,虽然这不是问题,但我会记住它。

以上是关于带有 python 扭曲服务器的 Qt C++ tcp 客户端的主要内容,如果未能解决你的问题,请参考以下文章

带有扭曲的 Hi-lo 游戏

如果服务器不允许SSH连接,可以扭曲SFTP客户端吗?

带有listentcp的扭曲IRCClient

具有非内联汇编的 Qt C++ 项目

Qt/OpenGL - 渲染的图元被扭曲

在 python 中从服务器发送一些行到 QT(C++) 客户端