【问题标题】:Qt: Python tcp client sends data over socket. How to read these bytes with Qt?Qt:Python tcp 客户端通过套接字发送数据。如何用 Qt 读取这些字节?
【发布时间】:2010-01-25 07:10:15
【问题描述】:

情况: 我有用 Python 制作的 tcp 客户端和用 Qt 制作的 tcp 服务器。我尝试用我的客户端发送字节,但我无法让 Qt 服务器读取这些字节。

使用 Python 制作的客户端和服务器,一切正常。我也可以让我的 Python 客户端毫无问题地与 C# 服务器一起工作。

Python 客户端代码:

import socket
import sys

HOST = 'localhost'
PORT = 50505

try:
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as msg:
    sys.stderr.write("[ERROR] %s\n" % msg)
    sys.exit(1)

try:
    sock.connect((HOST, PORT))
except socket.error as msg: 
    sys.stderr.write("[ERROR] %s\n" % msg)
    sys.exit(2)

sock.send(b'Hello World!\r\n')

我已经尝试过 e.q fortuneserver/fortuneclient 代码示例,但它们不起作用。 Bytesavailable() 始终为 0。

所以问题是如何在我的 Qt 应用程序中读取“Hello World!”线 ?我只需要在服务器发出 newConnection() 信号时启动的函数。

connect(tcpServer, SIGNAL(newConnection()), this, SLOT(startRead()));

更新:

Qt服务器部分代码:

void Server::startRead()
{
QDataStream in(tcpSocket);
in.setVersion(QDataStream::Qt_4_0);
QString ipAddress;

if (blockSize == 0) {
    if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
        return;
    in >> blockSize;
}

if (tcpSocket->bytesAvailable() < blockSize)
    return;

QString nextFortune;
in >> nextFortune;

statusLabel->setText(nextFortune);

    ABOVE IS FROM FORTUNE CLIENT EXAMPLE. 

    BELOW IS FROM ANOTHER EXAMPLE.
/*
char buffer[128] = {0};
QTcpSocket *client = tcpServer->nextPendingConnection();
qDebug() << client->bytesAvailable();
for (int i=0; i<100; i++)
{
    client->read(buffer, client->bytesAvailable());
    qDebug() << buffer;
    std::string sString(buffer);
    QString qString(sString.c_str());
    statusLabel->setText(qString);
}
    */
}

最后一部分相当糟糕。我试图做点什么,但我不知道我在用 Qt 做什么:)

【问题讨论】:

  • 您的客户端代码看起来不错(除了缩进混乱)。你可以发布你的服务器端吗?如果您尝试使用相同的客户端从 Web 上的随机 http 服务器获取某些内容,它就可以正常工作。另外,QT 与这整件事有什么关系?那是一个 GUI 工具包。
  • @Ibrahim - Qt 不是 GUI 工具包。它是一个应用程序框架。
  • 啊,好吧。谢谢。但是,如果没有服务器端代码,我认为这是不可调试的。
  • 肯定需要服务端代码提供有用的建议。

标签: python debugging qt sockets tcp


【解决方案1】:

您需要安排在有可用数据时读取您的代码。根据您的描述,startRead() 运行时还没有可用的数据。

我假设你打电话给QTcpServer::nextPendingConnection 是为了在startRead() 中获取你的tcpSocket?如果没有,您需要这样做。

只需将readyRead 信号从tcpSocketclient 连接到doRead() 插槽,然后检查bytesAvailable() 并在该插槽中读取。

每当有新数据到达时,都会调用此插槽。

您可能还对来自 TCP 套接字的 disconnected() 信号感兴趣,以了解它何时完成发送数据。

【讨论】:

    【解决方案2】:

    您附加的服务器代码是这样工作的:每个“数据包”(逻辑数据包)都包含一个 size 字段,然后是 size 的数据。

    基本上是这样的:

    1. 阅读quint16,如果没有 足够的字节被读取,等待 更多。
    2. quint16阅读,等我们有 至少quint16的数量 供阅读。
    3. 一旦我们有足够的,我们可以阅读 数据。

    在我们了解之后,即使您按照服务器期望的方式编写数据包长度,您尝试执行的操作仍然无法正常工作。这是因为服务器从套接字读取QString 的方式。客户端正在编写一个原始 python 字符串,我猜它只是将一个普通的旧 ASCII 写入套接字。服务器使用QDataStream 从套接字读取(这是在Qt 中序列化的标准方式)。如果您查看QString 的操作符here 的实现,它的作用远不止读取一个ASCII 字符串。

    如果您无法更改您的服务器,请更改您的客户端。您可以在 PyQt 附带的示例中看到 fortune 客户端的实现。

    【讨论】:

      猜你喜欢
      • 2014-12-01
      • 2013-12-26
      • 1970-01-01
      • 2015-08-13
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 2013-09-16
      • 1970-01-01
      相关资源
      最近更新 更多