2016-07-19 16 views
0

Die qt Dokumentation für QIODevice::Write sagt:QTcpSocket :: schreiben - wie schreibe ich große Dateien?

qint64 QIODevice::write(const char *data, qint64 maxSize) 

Schreibt höchstens maxSize Bytes von Daten von Daten an das Gerät. Gibt die Anzahl der Bytes zurück, die tatsächlich geschrieben wurden, oder -1, wenn ein Fehler aufgetreten ist.

Aber jeder Codebeispiel ich online scheint gefunden dies wie folgt zu verwenden:

QByteArray block; 
... fill the block... 
socket->write(block); 

oder wie folgt

QByteArray block; 
... fill the block... 
auto written_bytes = socket->write(block); 
if(written_bytes < block.size()) 
    throw error().. 

Angenommen, ich habe eine große Datei (sagen wir, 2 GB) zu senden, sollte ich den ersten oder den zweiten Ansatz verwenden? Ich bezweifle, dass 2 GBs in nur einem Stück über TCP gesendet werden können, oder?

Oder sollte ich eher etwas wie das folgende verwenden?

QByteArray block; 
... fill the block with 2GB of data... 
auto written_bytes = 0; 
while(written_bytes < 2GB) { 
    // Restart each time where we previously left 
    written_bytes += socket->write(block + written_bytes, 2GB - written_bytes); 
} 

Ich bin ganz verwirrt

+1

Die praktische TCP/IP-Paketgröße (MTU über Ethernet) beträgt etwa 1500 Byte. Ihre Daten werden also chunked. Schreiben Sie, was für Sie am offensichtlichsten und leicht zu pflegen ist. –

+0

Oh, also ist es absolut sicher/vernünftig für sagen wir mal ein kleines "Ping" von 5-6 Bytes, um einfach einen Fehler auszulösen, wenn 'write' diese 5-6 Bytes nicht schreiben könnte? – Dean

+1

Lesevorgänge/Schreibvorgänge werden blockiert, es sei denn, Sie verwenden nicht blockierende Sockets. –

Antwort

2

Sie müssen die Datei in ziemlich große Stücke halten lesen, und füttern diese Brocken in die Steckdose. Sie können die Chunk-Größe im laufenden Betrieb anpassen, um den Socket mit geringem Overhead zu streamen, d. H. Ihr Code, der auf ein niedriges Sendepuffer-Wasserzeichen reagiert, sollte nicht mehr als ein Dutzend Mal pro Sekunde aktiv sein. Für sehr große Dateien, wie in Ihrem Fall, sollten Sie einmal pro Sekunde nachfüllen.

Siehe zum Beispiel Code this answer.