2017-12-25 11 views
0

Wenn im BlockiermodusWie viele Daten wurden übertragen?

bytesTransferred = fileIChannel.transferTo(0, fileIChannel.size(), socketChannel); 
// or using a buffer 
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024*8); 
while (fileIChannel.read(byteBuffer) != -1) { 
byteBuffer.flip(); 
bytesTransferred += socketChannel.write(byteBuffer); 
byteBuffer.clear(); 

Im Falle eines Verbindungsfehlers eine Datei über Buchse übertragen, muss ich übertragen, um die Anzahl von Bytes halten. Ich kann dies tun, indem ich auf eine Antwort alle vom Server warten, wenn es eine bestimmte Anzahl von Bytes empfängt. Oder, wenn die Verbindung wiederhergestellt ist, sende ich eine Anfrage nach der Anzahl der empfangenen Bytes. Welche der Optionen wird korrekter sein? Wie wird dieses Problem normalerweise gelöst?

Und die zweite Frage. Ist die Datenintegrität gewährleistet, wenn große Daten über einen Socket gesendet werden?

+0

Ich bin mir nicht sicher, was Sie glauben, was Ihr Code macht. Sie sollten nicht nur gegen -1 prüfen ... Aber dann sehen Sie, wie viele Bits wirklich gelesen wurden. Weil diese Zahl für jeden Aufruf von read() variieren kann. Und ja, die TCP-Schicht macht ein bisschen Fehlererkennung. Sie sollten in der Lage sein, dies selbst zu erforschen. – GhostCat

+0

@GhostCat Danke. Die Methode 'flip()' begrenzt die Anzahl der tatsächlich gelesenen Daten. –

Antwort

1

Mit diesem Code können Sie nicht sagen. Wenn Sie wissen möchten, dass die Peer-Anwendung gesendete Daten empfangen und verarbeitet hat, muss Ihnen die Peer-Anwendung dies mitteilen. TCP puffert an beiden Enden, so dass die API es Ihnen nicht sagen kann.

Hinweis Ihre Kopierschleife ist falsch. Es sollte sein:

while ((fileIChannel.read(byteBuffer) != -1 && byteBuffer.position() > 0) 
{ 
    byteBuffer.flip(); 
    bytesTransferred += socketChannel.write(byteBuffer); 
    byteBuffer.compact(); 
} 

und es sollte auch ein Fehler Test beim Schreiben sein. Derzeit gehen Sie davon aus, dass bei jedem Schreibvorgang alles in die SocketChannel geschrieben wurde, was im nicht blockierenden Modus nicht garantiert ist.

Der Code mit transferTo() ist auch falsch, da transferTo() nicht garantiert die gesamte Übertragung durchführen: deshalb gibt es eine Zählung zurück. Sie müssen Schleife.

Verwandte Themen