Qt:Python tcp客户端通过套接字发送数据。如何用Qt读取这些字节?

时间:2010-01-25 07:10:15

标签: python debugging qt sockets tcp

情况: 我有用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做什么:)

2 个答案:

答案 0 :(得分:1)

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

我假设你打电话QTcpServer::nextPendingConnectiontcpSocket进入startRead()?如果没有,你需要这样做。

只需将readyReadtcpSocket的{​​{1}}信号连接到client广告位,然后查看doRead()并阅读该广告位。

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

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

答案 1 :(得分:0)

您附加的服务器代码以这种方式工作:每个“数据包”(逻辑1)都由size字段组成,并跟随size个数据。

基本上它是这样的:

  1. 如果没有,请阅读quint16 足够的字节要读,等待 更多。
  2. quint16阅读,等到我们有 至少quint16的金额 待阅读。
  3. 一旦我们有足够的,我们就可以读入 数据。
  4. 在我们理解之后,即使您像服务器期望的那样编写数据包长度,您尝试做的仍然无效。这是因为服务器从套接字读取QString的方式。客户端正在写一个原始的python字符串,我猜它只是在套接字上写一个普通的旧ASCII。服务器使用QDataStream从套接字读取(这是在Qt中序列化的标准方法)。如果你看一下QString的运算符&lt;&lt;的实现here,它不仅仅是读取ASCII字符串。

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