【问题标题】:Qt: Using QTcpSocket -> I can write on socket, but I can't read...Qt:使用 QTcpSocket -> 我可以在套接字上写,但我不能读...
【发布时间】:2017-02-03 13:30:40
【问题描述】:

我在 xUbuntu 14.04 上使用 Qt 4.8 GCC 32 位。
我有以下代码,一个 TCP 服务器,我使用它来获取一些远程命令并发送回一些答案 - 通过 TCP 套接字:

struct _MyRequest
{
    unsigned long   Request;
    unsigned long   Data;
} __attribute__((packed));

struct _MyAnswer
{
    unsigned long   Error;
    unsigned long   Filler;
} __attribute__((packed));

_MyRequest request;
_MyAnswer  answer;

RemoteCmdServer::RemoteCmdServer(QObject * parent)
    : QTcpServer(parent)
{
    qDebug() << "Server started";

    listen(QHostAddress("172.31.250.110"), 5004);

    connect(this, SIGNAL(newConnection()), this, SLOT(processPendingRequest()));
}

void RemoteCmdServer::processPendingRequest()
{
    qDebug() << "Process request";

    QTcpSocket * clientConnection = nextPendingConnection();
    connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater()));

    // get the request
    int ret = clientConnection->read((char*)&request, sizeof(request));
    qDebug() << "READ: " << ret;
    if(ret == sizeof(request))
    {
        // send answer
        clientConnection->write((char*)&answer, sizeof(answer));
    }

    qDebug() << "Disconnecting...";
    clientConnection->disconnectFromHost();
}   

如果我评论if(ret == sizeof(request)) 行,我就能正确书写。
然而,我无法从套接字读取(我总是得到 0 个字节)。
我 100% 确定我用来向我的应用程序发送数据包的 TCP 工具工作正常。
这是我的应用程序的调试输出:

Server started     
Process request    
READ: 0     
Disconnecting...     

我做错了什么?请指教!

【问题讨论】:

  • 您必须先等待数据可用,然后再尝试读取。见the docs
  • 我尝试了 1000 毫秒...它似乎不起作用... :(
  • 你能编辑你的问题并展示你是如何尝试的吗?您确定在这 1 秒期间发送了数据吗?
  • 只有几个字节,不是很大的数据量...我什至尝试等待 3 秒,但什么也没有... :(
  • 请继续等待,直到您获得预期获得的字节数。

标签: c++ qt sockets tcp


【解决方案1】:

您正在尝试从新连接读取数据而不返回 Qt 事件循环——我认为这不会起作用。

在您接受连接后...

QTcpSocket * clientConnection = nextPendingConnection();

您需要使用类似...的方式连接到它的readyRead 信号

connect(clientConnection, SIGNAL(readyRead()), this, SLOT(my_read_slot()));

其中my_read_slot 是实际执行读取操作的成员函数。

【讨论】:

    【解决方案2】:

    您应该以非阻塞或阻塞方式等待数据。您可以使用waitForReadyRead 以阻塞方式进行操作。

    void RemoteCmdServer::processPendingRequest()
    {
        qDebug() << "Process request";
    
        QTcpSocket * clientConnection = nextPendingConnection();
        connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater()));
    
        if (clientConnection->waitForReadyRead())
        {
            // get the request
            QByteArray message = clientConnection->readAll(); // Read message
            qDebug() << "Message:" << QString(message);
        }
        else
        {
            qDebug().nospace() << "ERROR: could not receive message (" << qPrintable(clientConnection->errorString()) << ")";
        }
    
        qDebug() << "Disconnecting...";
        clientConnection->disconnectFromHost();
    }
    

    【讨论】:

    • 我尝试使用clientConnection-&gt;waitForReadyRead(3000);,但它根本不起作用。 -> 阅读:0
    • 我更新了我的示例代码。尝试使用 readAll() 读取客户端消息。
    • 调用socket-&gt;waitForReadyRead(1000);后显示:“网络操作超时”
    • 您也可以尝试使用默认值 30000 来查看 1 秒是否太早
    • 我已经尝试过 3 秒、30 秒等,但它也不起作用。似乎问题出在其他地方,我暂时不知道。我希望比我聪明的人会想出一些其他的想法。谢谢:)
    猜你喜欢
    • 2018-02-12
    • 1970-01-01
    • 2021-05-09
    • 2015-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    相关资源
    最近更新 更多