2014-10-06 149 views
1

我想使用qtcpsocket连接在服务器和客户端之间发送数据。当我发送小尺寸数据时,一切都很好。但是,当尺寸增加了数据读取的TCPSocket转为空:(。QTcpSocket连接传入的空数据问题

//使连接

bool ClientService::enableConnection() 
{ 
    qDebug() << Q_FUNC_INFO << "Invoked"; 
    const int iTimeout = 5 * 1000; 
    m_socket.connectToHost(settings.getServerIP(), PORT); 
    if (!m_socket.waitForConnected(iTimeout)) 
    { 
     emit error(); 
     qDebug() << Q_FUNC_INFO << m_socket.errorString(); 
     return false; 
    } 

    qDebug() << Q_FUNC_INFO << "Exits"; 
    return true; 
} 

//将数据发送到服务器一旦所有数据被写入到QDataStream

bool ClientService::sendToServer(QByteArray block) 
{ 
    qDebug() << Q_FUNC_INFO << "Invoked"; 
    bool sendStatus = false; 
    if (QTcpSocket::ConnectedState == m_socket.state()) 
    { 
     if (-1 != m_socket.write(block)) 
     { 
      m_socket.waitForBytesWritten(); 
      sendStatus = true; 
     } 
     else 
     { 
      qDebug() << Q_FUNC_INFO << "error in write"; 
     } 
    } 
    else 
    { 
     qDebug() << Q_FUNC_INFO << "socket is not connected"; 
    } 

    if (!sendStatus) 
    { 
     qDebug() << Q_FUNC_INFO << "emits error signal"; 
     emit error(); 
    } 

    qDebug() << Q_FUNC_INFO << "Exits" << sendStatus; 
    return sendStatus; 
} 

//等待,直到从服务器收到响应

bool ClientService::waitForServerResponse() 
{ 
    qDebug() << Q_FUNC_INFO << "Invoked"; 
    const int iTimeout = 5 * 1000; 
    while (m_socket.bytesAvailable() < (int)sizeof(quint16)) 
    { 
     if (!m_socket.waitForReadyRead(iTimeout)) 
     { 
      emit error(); 
      qDebug() << Q_FUNC_INFO << m_socket.errorString(); 
      return false; 
     } 
    } 

    quint16 blockSize; 
    QDataStream inputStream(&m_socket); 
    inputStream.setVersion(QDataStream::Qt_4_0); 
    inputStream >> blockSize; 

    while (m_socket.bytesAvailable() < blockSize) 
    { 
     if (!m_socket.waitForReadyRead(iTimeout)) 
     { 
      emit error(); 
      qDebug() << Q_FUNC_INFO << m_socket.errorString(); 
      return false; 
     } 
    } 

    qDebug() << Q_FUNC_INFO << "Exits"; 
    return true; 
} 

//禁用连接一旦收到响应

void ClientService::disableConnection() 
{ 
    qDebug() << Q_FUNC_INFO << "Invoked"; 
    m_socket.disconnectFromHost(); 
    qDebug() << Q_FUNC_INFO << "Exits"; 
    return; 
} 

//要发送的数据

int ClientService::syncMasters(SyncMaster syncMasterData) 
{ 
    qDebug() << Q_FUNC_INFO << "Invoked"; 

    int syncStatus = -1; 

    if(enableConnection()) 
    { 
     qDebug() << Q_FUNC_INFO << "connection enabled"; 
     // typecast to ensure cross platform compatibility 
     const qint32 mode_int = static_cast<qint32>(SYNC_MASTERS_QUERY); 
     QByteArray block; 
     QDataStream outputStream(&block, QIODevice::WriteOnly); 
     outputStream.setVersion(QDataStream::Qt_4_0); 
     outputStream << (quint16)0; 
     outputStream << mode_int;  // saying query mode to server 

     // group master data 
     outputStream << syncMasterData.groupMasterList.count(); 
     qDebug() << Q_FUNC_INFO << "groupmaster count" << 
            syncMasterData.groupMasterList.count(); 

     foreach (GroupMaster groupMasterItem, syncMasterData.groupMasterList) 
     { 
      outputStream << groupMasterItem.groupCode; 
      outputStream << groupMasterItem.groupDescription; 
      outputStream << groupMasterItem.kotPrinterNo; 
      outputStream << groupMasterItem.image; 
      outputStream << groupMasterItem.sortId; 

      qDebug() << Q_FUNC_INFO << 
         "code"  << groupMasterItem.groupCode   << 
         "desc"  << groupMasterItem.groupDescription << 
         "kot "  << groupMasterItem.kotPrinterNo  << 
         "image"  << groupMasterItem.image    << 
         "sort id" << groupMasterItem.sortId; 
     } 

     // subgroup master data 
     outputStream << syncMasterData.subGroupMasterList.count(); 
     qDebug() << Q_FUNC_INFO << "subgroupmaster count" << 
            syncMasterData.subGroupMasterList.count(); 

     foreach (SubGroupMaster subGroupMasterItem, 
           syncMasterData.subGroupMasterList) 
     { 
      outputStream << subGroupMasterItem.groupCode; 
      outputStream << subGroupMasterItem.subGroupCode; 
      outputStream << subGroupMasterItem.subGroupDescription; 

      qDebug() << Q_FUNC_INFO << 
        "gpcode" << subGroupMasterItem.groupCode  << 
        "subgpcode" << subGroupMasterItem.subGroupCode << 
        "desc"  << subGroupMasterItem.subGroupDescription; 
     } 

     // item master data 
     outputStream << syncMasterData.itemMasterList.count(); 
     qDebug() << Q_FUNC_INFO << "item master count" << 
            syncMasterData.itemMasterList.count(); 

     foreach (ItemMaster ItemMasterItem, syncMasterData.itemMasterList) 
     { 
      outputStream << ItemMasterItem.itemCode; 
      outputStream << ItemMasterItem.itemName; 
      outputStream << ItemMasterItem.groupCode; 
      outputStream << ItemMasterItem.subGroupCode; 
      outputStream << ItemMasterItem.imagePath; 
      outputStream << ItemMasterItem.productId; 
      outputStream << ItemMasterItem.itemPriceType; 
      outputStream << ItemMasterItem.itemPrice; 
      outputStream << ItemMasterItem.kotPrinterNumber; 
      outputStream << ItemMasterItem.sortId; 

      qDebug() << Q_FUNC_INFO << 
         "item code"  << ItemMasterItem.itemCode  << 
         "item name"  << ItemMasterItem.itemName  << 
         "group code" << ItemMasterItem.groupCode  << 
         "subgp code" << ItemMasterItem.subGroupCode << 
         "image path" << ItemMasterItem.imagePath  << 
         "product id" << ItemMasterItem.productId  << 
         "item pricetype"<< ItemMasterItem.itemPriceType << 
         "item price" << ItemMasterItem.itemPrice  << 
         "kot"   << ItemMasterItem.kotPrinterNumber<< 
         "sortId"  << ItemMasterItem.sortId; 
     } 

     // side item master data 
     outputStream << syncMasterData.sideItemMasterList.count(); 
     qDebug() << Q_FUNC_INFO << "side item master count" << 
            syncMasterData.sideItemMasterList.count(); 

     foreach (SideItemMaster sideItemMasterItem, 
             syncMasterData.sideItemMasterList) 
     { 
      outputStream << sideItemMasterItem.itemCode; 
      outputStream << sideItemMasterItem.sideItemCode; 
      outputStream << sideItemMasterItem.lineNumber; 
      outputStream << sideItemMasterItem.sideItemPrice; 
      outputStream << sideItemMasterItem.sideItemPriceType; 

      qDebug() << Q_FUNC_INFO << 
        "item code"  << sideItemMasterItem.itemCode  << 
        "sideitem code" << sideItemMasterItem.sideItemCode << 
        "line no"  << sideItemMasterItem.lineNumber << 
        "sideitem pric" << sideItemMasterItem.sideItemPrice << 
        "siditm prc typ"<< sideItemMasterItem.sideItemPriceType; 
     } 

     // price master data 
     outputStream << syncMasterData.priceMasterList.count(); 
     qDebug() << Q_FUNC_INFO << "price master count" << 
            syncMasterData.priceMasterList.count(); 

     foreach (PriceMaster priceMasterItem, syncMasterData.priceMasterList) 
     { 
      outputStream << priceMasterItem.itemCode; 
      outputStream << priceMasterItem.itemPriceType; 
      outputStream << priceMasterItem.promoCode; 
      outputStream << priceMasterItem.validFromDate; 
      outputStream << priceMasterItem.validToDate; 
      outputStream << priceMasterItem.validFromTime; 
      outputStream << priceMasterItem.validToTime; 
      outputStream << priceMasterItem.unitCode; 
      outputStream << priceMasterItem.itemPrice; 
      outputStream << priceMasterItem.specialPrice; 
      outputStream << priceMasterItem.unitDescription; 

      qDebug() << Q_FUNC_INFO << 
         "item code"  << priceMasterItem.itemCode   << 
         "itm prc typ" << priceMasterItem.itemPriceType << 
         "promo code" << priceMasterItem.promoCode  << 
         "validfrmdt" << priceMasterItem.validFromDate << 
         "vld to dt"  << priceMasterItem.validToDate  << 
         "vld frm tm" << priceMasterItem.validFromTime << 
         "vld to tm"  << priceMasterItem.validToTime  << 
         "unit code"  << priceMasterItem.unitCode   << 
         "item price" << priceMasterItem.itemPrice  << 
         "spcl price" << priceMasterItem.specialPrice  << 
         "unit desc"  << priceMasterItem.unitDescription; 
     } 

     outputStream.device()->seek(0); 
     outputStream << (quint16)(block.size() - sizeof(quint16)); 

     if(sendToServer(block)) 
     { 
      qDebug() << Q_FUNC_INFO << "query sent to server successfully"; 

      if (waitForServerResponse()) 
      { 
       qDebug() << Q_FUNC_INFO << "read set status from server"; 

       QDataStream inputStream(&m_socket); 
       inputStream.setVersion(QDataStream::Qt_4_0); 
       inputStream >> syncStatus; 
      } 
     } 

     disableConnection(); 
    } 

    qDebug() << Q_FUNC_INFO << "Exits" << syncStatus; 
    return syncStatus; 
} 

//读取也相似

void ServerFunctionThread::syncMasters() 
{ 
    qDebug() << Q_FUNC_INFO << "Invoked"; 

    SyncMaster syncMasterData; 

    int groupCount  = 0, 
     subGroupCount = 0, 
     itemCount  = 0, 
     sideItemCount = 0, 
     priceCount  = 0; 

    QDataStream inputStream(&tcpSocket); 
    inputStream.setVersion(QDataStream::Qt_4_0); 

    // group master data reception 
    inputStream >> groupCount; 
    qDebug() << Q_FUNC_INFO << "group master Count" << groupCount; 

    while (groupCount--) 
    { 
     GroupMaster groupMasterItem; 
     inputStream >> groupMasterItem.groupCode; 
     inputStream >> groupMasterItem.groupDescription; 
     inputStream >> groupMasterItem.kotPrinterNo; 
     inputStream >> groupMasterItem.image; 
     inputStream >> groupMasterItem.sortId; 

     syncMasterData.groupMasterList.append(groupMasterItem); 

     qDebug() << Q_FUNC_INFO << 
        "code"  << groupMasterItem.groupCode   << 
        "desc"  << groupMasterItem.groupDescription << 
        "kot "  << groupMasterItem.kotPrinterNo  << 
        "image"  << groupMasterItem.image    << 
        "sort id" << groupMasterItem.sortId; 

    } 
. 
. 
... 

有人可以帮助我知道是否有大小限制的数据写入QDataStream ... 因为从我的日志连接仍然活着,我得到的回应。但是在读取少量数据后收到的数据是空的。

+3

收到而非套接字上等待字节可用,我建议使用与QTcpSocket的数据大小readyRead信号让你知道数据何时可用:http://qt-project.org/doc/qt-4.8/qiodevice.html#readyRead – TheDarkKnight 2014-10-06 08:24:02

+0

你也可以在将数据写入套接字后调用flush() – 2014-10-06 08:26:39

+0

@ Merlin069:至于ik现在,每次有新数据可用时,readyRead都会发出。所以我应该得到数据一次完整的数据按正确的顺序读取 – Abin 2014-10-06 08:31:13

回答

0

问题已解决。 :)

从客户端传递到服务器的数据大小造成了问题。由于我使用quint16当数据的大小变得更大时,服务器无法知道确切的传入数据大小。所以我改变了类型为quint32。问题就解决了。

outputStream << (quint32)0; 

//和结束

outputStream.device()->seek(0); 
outputStream << (quint32)(block.size() - sizeof(quint32)); 

和服务器端也等待在quint32