2017-10-12 5 views
2

QTcpServer가 있습니다. 클라이언트 측에서 큰 데이터를 보내고 모든 데이터가 서버에서 수신되면 신호를 잡는 방법을 원하십니까? "while (socket-> bytesavailable)"이 작동하지 않습니다. 이에QTcpSocket readyRead() 신호가 두 번 울립니다.

:

qbytearray 크기가 4000 또는 5000의 서버, 클라이언트에서 보내는 9000입니다 ...

예 2 : 예를 들어

Case readyRead() SIGNAL Emitted 8 회입니다.

void Client::SendMessage(std::vector<QString>) 
{ 
    MyClass _Send; 
      _Send.Age = 22; 
      _Send.School = 14; 
      _Send.Name = "Taz"; 

    QVector<MyClass2> vv; 

    for (int i = 0; i < 15000; i++) { 
     vv.push_back(MyClass2(24, "leri")); 
     vv.push_back(MyClass2(22, "tazo")); 
    } 

    _Send.vctr = vv; 

    QByteArray bytes; 
    QDataStream stream(&bytes, QIODevice::WriteOnly); 

    int FunctionUID = 331; 
    int ij, ik = ij = 169; 
    MyClass2 faf(-31, "15"); 

    stream << FunctionUID << _Send << faf << ij << ik; 

    socket->write(bytes); 
} 



void Server::ImReady() 
{ 
    QByteArray buf; 

    buf = socket->readAll(); 

    QDataStream stream(&buf, QIODevice::ReadOnly); 

    int FunctionUID, ij, ik; 
    MyClass vv; 
    MyClass2 vv1; 

    stream >> FunctionUID >> vv >> vv1 >> ij >> ik; 

    qDebug() << vv.vctr.size() << "faf"; 
} 

void Server::incomingConnection(qintptr val) 
{ 
    qDebug() << "Client Connected" << val; 

    socket = new QTcpSocket; 
    socket->setSocketDescriptor(val); 

    if (!socket) { 
     return; 
    } 

    connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater())); 
    connect(socket, SIGNAL(readyRead()), this, SLOT(ImReady())); 
} 
+0

데이터가 항상 단일 패킷으로 전송되는 것은 아닙니다. 크기가 클 경우 데이터 덩어리로 보낼 수 있습니다. 이것은 아마도 여러 개의'readyRead' 신호를받는 이유 일 것입니다. – vahancho

+0

Qt 5.7 또는 그 이후 버전을 사용하고 있다면'QDataStream'에서 [read transactions] (http://doc.qt.io/qt-5/qdatastream.html#using-read-transactions)를 이용할 수 있습니다. [fortune 클라이언트 예제] (http://doc.qt.io/qt-5/qtnetwork-fortuneclient-example.html)에서 구현 방법을 확인하십시오. – thuga

답변

3

TCP는 메시지를 보내지 않으며 데이터 스트림입니다. 즉, 거기에있는 모든 데이터를 읽을 수는 없으며이 메시지를 고려해야합니다. 대신 하나는 일반적으로 메시지 크기를 포함하는 헤더를 보내고 수신기는 전체 메시지 (그리고이 메시지를 읽지 않고 다음 메시지로 읽지 않음)를 읽는 데 얼마나 많은 양을 알고 있습니다.

이 당신은 슬롯의 시작 부분에

if (socket->bytesAvailable() == 0) 
    return; 

같은 줄을 추가 할 수 귀하의 슬롯이

void Server::ImReady() 
{ 
    uint32 size; 
    socket->read(&size, 4); 
    uint32 readTotal = 0; 
    do { 
    readTotal += socket->read(buffer, size-readTotal); 
    } while (readTotal < size); 
} 

같은 것을 할 것입니다 의미, 그리고 당신은 모든 경우에 신경 쓰지 것 신호는 메시지 당 두 번 이상 방출됩니다.

위의 코드는 추가적인 오류 처리가 필요합니다. 첫 번째 read이 4 바이트를 모두 읽고 항상 -1의 반환 값을 처리해야합니다.

+0

나는 이것이 매우 도움이된다고 생각한다. 그러나 나는 총 문제가있다. 지금은 나와 함께 'uint32' 과 일치하는 호출 socket-> read (QByteArray) – Taz742

+0

에 대한 오버로드가있다. 'QTcpSocket :: read'에 대한 오버로드가있다. 읽은 바이트 수를 반환하고, 다른 하나는'QByteArray'를 반환합니다. 사용하는 코드에 따라 코드를 수정해야합니다. 대답의 코드는 바이트 배열을 사용할 것이고,'buffer'는 간단한'char []' –

+0

이 문제가 해결되었습니다.) – Taz742

관련 문제