【问题标题】:Qt Socket not waiting for bytes writtenQt Socket 不等待写入的字节
【发布时间】:2015-04-27 08:54:15
【问题描述】:

我编写了一个国际象棋客户端/服务器移动应用程序,并有一个远程服务器,该服务器已在西海岸、东海岸等地进行了测试。简而言之,该程序是这样的:

1.  Log in to remote server with correct username/password via iOS/Android or Windows desktop.
2.  Enter queue for a 1-minute, 5-minute or 30-minute game of chess.
3.  Wait for another opponent to join queue.
4.  Get matched and play game of chess.
5.  When game is over, log out or play more chess.

但是,当我通过学校的互联网登录服务器时,我遇到了最奇怪的错误。这太奇怪了,因为它是我连接的众多 ISP 中唯一存在问题的 ISP。

当我通过学校的互联网登录服务器时,我会从我的套接字中收到以下错误和错误字符串。

QAbstractSocket::UnknownSocketError "Unknown error"

在我的应用程序中生成这个的步骤是:

1. Enter username and password, log into server. (Successfully completes this).

2. Click to join a queue for a game of chess.  (Successfully writes to socket, but fails to wait for bytes written then emits the above error and error string.

我检查了服务器,甚至没有调用 readyRead(),所以我知道客户端没有向服务器发送任何内容。

有趣的是,我找到了解决此错误的解决方法。

1.  Click on Settings page.
2.  Click Save. (Does the exact same thing as I try to do above.  Write to socket, flush and wait for bytes written).
3.  Join queue (Successfully joins queue).

该解决方法毫无意义,因为它所做的事情与我在上面尝试做的事情没有什么不同(写入套接字、刷新并等待写入的字节)。

有人知道可能发生了什么吗?

  1. 为什么此错误特定于 ONE Internet 位置?我学校的网速慢得要命,但没有在下面的函数中解释为什么套接字会立即断开。
  2. 为什么我的解决方法有效?
  3. 我可以做些什么来详细了解我的问题(即愚蠢的错误消息...“未知错误”)。
  4. 不仅如此,当我右键单击下面的功能,然后单击“查找用法”时,会出现构建文件夹。这是程序中唯一执行此操作的函数。什么鬼???

此函数中的套接字断开连接。

 void CG_serverConnection::sendQueueType(int timeControl)
 {
    //Create local JSON object
    QJsonObject userInfo;

    //Create object
    userInfo["PacketHeader"] = QUEUE_REQUEST;
    userInfo["TimeControl"] = timeControl;

    //Create JSON document
    QJsonDocument doc;
    doc.setObject(userInfo);

    qDebug() << "Send queue type called! ";
    qDebug() << doc.toJson();

    QByteArray byteArray = doc.toBinaryData();

    //Send over socket
    if(m_socket->write(byteArray))
    {
        qDebug() << "Wrote to socket";
    }
    else
        m_socket->errorString();
    if(m_socket->flush())
    {
        qDebug() << "Flushed";
    }
    else
        qDebug() << m_socket->errorString();

    if(m_socket->waitForBytesWritten(50000))
    {
        qDebug() << "Bytes were written.";
    }
    else
    {
       qDebug() << m_socket->error();
       qDebug() << m_socket->errorString();
    }
}

我在哪里调用函数

    Button
    {
        id: btn_oneMinuteGame
        text: "One Minute"
        style: cgButtonStyle

        Layout.alignment: Qt.AlignCenter
        Layout.preferredWidth: Lobby.getControlWidth()
        Layout.preferredHeight: Lobby.getControlHeight()

        onClicked:
        {
            ServerConnection.sendQueueType(1) // TODO : Magic numbers
            root.startOneMinuteGame()
        }
    }

【问题讨论】:

  • socket真的连接成功了吗?请注意,connectToHost() 只是触发异步连接,一旦 connectToHost() 返回,套接字就不会立即连接。还要检查 write() 的返回值。
  • 是的,它确实连接了。 write() 的返回值为 68。我不知道这是什么意思。
  • 等等,我有什么要说的吗?我猜 68 是它尝试写入的字节数。 m_socket->write() 方法返回一个 qint64。我是否会导致 68 字节而不是最大 64 字节的溢出?还是我在这里偏离了目标?
  • 如果你从 write 得到 68,这意味着 68 个字节被写入。在这种情况下,flush 返回 false,因为没有要刷新的内容。字节已经写入。而当 flush 返回 false 时,qDebug() errorString(); 返回 'unknown error' 因为在完全没有错误时也会返回。
  • qint64 是一个 64 位整数。它可以容纳 68 个就好了;)

标签: c++ qt networking tcp


【解决方案1】:

由于某种原因,如果我在函数顶部调用它,一切正常...

没有意义。如果有人可以解释为什么这样做或您有其他解决方案,请发布。

//Temporary bug fix
this->sendUpdatedUserInfo();

我称之为以某种方式使一切正常工作的函数

void CG_serverConnection::sendUpdatedUserInfo()
{
    QJsonObject request;

    request["PacketHeader"] = UPDATE_INFO;
    request["loggedIn"]     = m_player.loggedIn;
    request["banned"]       = m_player.banned;
    request["username"]     = m_player.username;
    request["elo"]          = m_player.elo;
    request["countryFlag"]  = m_player.countryFlag;
    request["pieceSet"]     = m_player.pieceSet;
    request["language"]     = m_player.language;
    request["sound"]        = m_player.sound;
    request["coordinates"]  = m_player.coordinates;
    request["arrows"]       = m_player.arrows;
    request["autoPromote"]  = m_player.autoPromote;
    request["boardTheme"]   = m_player.boardTheme;

    QJsonDocument doc;
    doc.setObject(request);

    qDebug() << "Updated userInfo being sent: ";
    qDebug() << doc.toJson();

    m_socket->write(doc.toBinaryData());
    m_socket->flush();
    m_socket->waitForBytesWritten();
}

【讨论】:

  • 您的问题与您的国际象棋游戏等所有不相关的引用太混淆了。在 Wireshark 中跟踪连接,看看到底发生了什么。
  • 会的。感谢您提供有关使用 Wireshark 的提示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-15
  • 1970-01-01
  • 2019-12-10
  • 1970-01-01
  • 1970-01-01
  • 2013-08-27
  • 2014-02-19
相关资源
最近更新 更多