Probleme beim Senden von Paketen

Alles rund um die Programmierung mit Qt
Antworten
Woodfighter
Beiträge: 9
Registriert: 6. Juli 2012 21:09

Probleme beim Senden von Paketen

Beitrag von Woodfighter »

Hallo Qt-Forum!

Ich möchte Daten in maximal 256 Byte große Pakete einteilen und diese dann über ein TCP-Socket versenden.
Dummerweise werden die Pakete nicht alle versendet, wenn es zu viele gibt.

Ein Beispiel: Ich habe 128 Pakete. Auf der Empfängerseite ließ ich einen Counter mitlaufen und ihn ausgeben. Laut dem Counter bin ich nur bis zum 124. Paket gekommen, dann kamen keine Pakete mehr an.

Ich habe es bereits mit einem flush() versucht, natürlich ohne Erfolg.
Methode zum Senden der Daten:

Code: Alles auswählen

void Action::sendDataSecure()
{

    qint64 packets;
    qint64 lastPacketSize;
    int dataSize = this->m_writeBuffer->getDataBuffer().size();

    if(dataSize > m_packetSize)
    {
        if(dataSize % m_packetSize == 0)
        {
            packets = dataSize / m_packetSize;
            lastPacketSize = m_packetSize;
        }
        else
        {
            packets = (dataSize / m_packetSize) + 1;
            lastPacketSize = dataSize - ((packets - 1) * m_packetSize);
        }
    }
    else
    {
        packets = 1;
        lastPacketSize = dataSize;
    }

    qint64* packetsPtr = &packets;
    qint64* lastPacketSizePtr = &lastPacketSize;
    const char* sendPacketsPtr = reinterpret_cast<const char*>(packetsPtr);
    const char* sendLastPacketSizePtr = reinterpret_cast<const char*>(lastPacketSizePtr);
    this->m_client->getTCPSocket()->write(sendPacketsPtr, sizeof(qint64));
    this->m_client->getTCPSocket()->write(sendLastPacketSizePtr, sizeof(qint64));
    this->m_client->getTCPSocket()->write(this->m_writeBuffer->getHeader(), sizeof(qint64));

    qint64 pos = 0;
    QString sectionData = this->m_writeBuffer->getDataBuffer();

    int testCounter = 0;
    for(; packets > 0; -- packets)
    {
        if(packets == 1)
        {
            const char* data = sectionData.section("", pos, pos + lastPacketSize).toStdString().c_str();
            this->m_client->getTCPSocket()->write(data, lastPacketSize);
        }
        else
        {
            const char* data = sectionData.section("", pos, pos + m_packetSize).toStdString().c_str();
            this->m_client->getTCPSocket()->write(data, m_packetSize);
        }
        pos += m_packetSize + 1;
        ++ testCounter;

    }
}
Methode zum Empfangen der Daten:

Code: Alles auswählen

void Action::readSecureData()
{
    if(this->m_numberOfPackets == -1)
    {
        if(this->m_client->getTCPSocket()->bytesAvailable() >= (qint64)sizeof(qint64))
        {
            this->m_numberOfPackets = (*(qint64*)this->m_client->getTCPSocket()->read(sizeof(qint64)).data());
        }
        else
        {
            return;
        }
    }

    if(this->m_lastPacketSize == -1)
    {
        if(this->m_client->getTCPSocket()->bytesAvailable() >= (qint64)sizeof(qint64))
        {
            this->m_lastPacketSize = (*(qint64*)this->m_client->getTCPSocket()->read(sizeof(qint64)).data());
        }
        else
        {
            return;
        }
    }

    if(this->m_headerBuffer.size() == 0)
    {
        if(this->m_client->getTCPSocket()->bytesAvailable() >= (qint64)sizeof(qint64))
        {
            this->m_headerBuffer = this->m_client->getTCPSocket()->read(sizeof(qint64)).data();
        }
        else
        {
            return;
        }
    }

    qint64 packets = this->m_numberOfPackets;

    while(this->m_numberOfPackets > 0)
    {
        if(this->m_numberOfPackets == 1)
            this->m_readBuffer += this->m_client->getTCPSocket()->read(this->m_lastPacketSize).data();
        else
            this->m_readBuffer += this->m_client->getTCPSocket()->read(m_packetSize).data();

        -- this->m_numberOfPackets;

    }


    Data* newData = new Data();
    newData->setHeader(this->m_headerBuffer);
    newData->setDataBuffer(this->m_readBuffer);
    this->m_readDataStorage.push_back(newData);
    this->m_numberOfPackets = -1;
    this->m_lastPacketSize = -1;
    this->m_readBuffer.clear();
    this->m_headerBuffer.clear();
    emit this->newData(this->m_client, newData, packets);


}
Danke für eure Antworten! Ich freue mich auch über andere Tipps, die ihr geben könnt! ;-)
ScyllaIllciz
Beiträge: 200
Registriert: 9. Juli 2010 19:31

Re: Probleme beim Senden von Paketen

Beitrag von ScyllaIllciz »

Hast Du mal die TCP Option "QAbstractSocket::LowDelayOption" probiert? Sonst kann es passieren das die Daten gesammelt werden bis max 1500 Byte (1 Frame) voll sind und dann erst gesendet werden. Das macht der TCP Stack des OS.

Hat bei mir solche Probleme gelöst.
Woodfighter
Beiträge: 9
Registriert: 6. Juli 2012 21:09

Re: Probleme beim Senden von Paketen

Beitrag von Woodfighter »

Habe es versucht, hat aber leider nicht geholfen.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Probleme beim Senden von Paketen

Beitrag von RHBaum »

Bei TCP kommen die daten definitiv an, sonst hasst nen ganz grundsaetzliches Problem .... oder du ignorierst errors ^^

generell fasst der Stack packete zusammen, weswegen du bei TCP nicht packetorientiert denken solltest ... sondern es ist ein datenstrom, quasi eine pipe, was auf der einen seite reinschiebst, kommt auf der anderen seite auch raus, nur die frage wann und wie ^^

Generell solltest du in erwaegung ziehen, nen Textbasiertes Protokoll zu verwenden .... wenn nicht grade die maximale performance vom netzt brauchst ...
Da tust dir mit debuggen leichter, und mit der richtigen codierung brauchst auch plattformspecificas ned beachten (falls mal aufn Android, Ios, irgendwas migrieren willst)
Mann kann auch binaerdaten ueber text schicken, nur dann verliert man den vorteil der Plattformunabhaengigkeit und muss diese selber implementieren ...

zeig eher mal deine empfangsseite an ...

Ciao ...
Antworten