2012-03-30 1 views
2

Ich habe große Datei zu trnasfer, in diesem Moment verwende ich TcpClient und NetworkStream-Klasse, um das zu tun, aber es ist nicht genug. Wenn ich NetworkStream.Write benutze und lese es verliere Bytes Ich weiß nicht, wie kann ich sicherstellen, dass TCP wird aufhören zu lesen, wenn alle Bytes in Ordnung sein wird.TcpClient VS Socket in großen Dateitransfer

Dann habe ich Socket-Klasse gefunden, und jetzt meine Frage, "Socket wird über alle Bytes vollkommen sicher sein, bevor es zu Ende gelesen?"

Wie ich Datei folgendes Datum:

  byte[] VideoFrom = new byte[FizeSizeSendedBefore]; 
      byte[] PartData = new byte[clientSocket.ReceiveBufferSize]; 
      int PartNumbers = (VideoSize/clientSocket.ReceiveBufferSize) + 1; 
      int lastPackageSize = VideoSize - ((PartNumbers - 1) * clientSocket.ReceiveBufferSize); 

      int i; 
      int bytesToRead = 0; 
      int ActualSize = 0; 
      for (i = 0; i < PartNumbers; i++) 
      { 
       if (i < PartNumbers - 1) 
       { 
        bytesToRead = clientSocket.ReceiveBufferSize; 
       } 
       else 
       { 

        bytesToRead = lastPackageSize; 
       } 
       ActualSize += bytesToRead; 


       PartData = new byte[bytesToRead]; 

       System.Threading.Thread.Sleep(2); 

       networkStream.Read(PartData, 0, bytesToRead); 

       Buffer.BlockCopy(PartData, 0, VideoFrom, i * clientSocket.ReceiveBufferSize, bytesToRead); 
      } 



      if (!Directory.Exists("./temp/anwsers/" + AnwserXML.Attribute("number").Value)) { Directory.CreateDirectory("./temp/anwsers/" + AnwserXML.Attribute("number").Value); } 
      File.WriteAllBytes("./temp/anwsers/" + AnwserXML.Attribute("number").Value + "/" + AnwserXML.Attribute("client").Value + ".mov", VideoFrom); 


     } 

Wie ich Datei

int PartNumber = (FizeSizeSendedBefore/ clientSocket.ReceiveBufferSize) + 1; 
      int lastPackageSize = FileSize - ((PartNumber - 1) * clientSocket.ReceiveBufferSize); 
      int i; 
      for (i = 0; i < PartNumber; i++) 
      { 
       if (i < PartNumber - 1) 
       { 
        while (!serverStream.CanRead) { } 
        serverStream.Write(outStream, i * clientSocket.ReceiveBufferSize, clientSocket.ReceiveBufferSize); 
       } 
       else 
       { 
        while (!serverStream.CanRead) { } 
        serverStream.Write(outStream, i * clientSocket.ReceiveBufferSize, lastPackageSize); 
       } 

      } 
+4

Ich bin sicher, dass es * nicht * Bytes verlieren. Ich bin sicher, das Problem ist irgendwo in Ihrem Code - aber es ist schwer zu sagen, wo, wenn Sie nicht Ihren Code gezeigt haben ... –

+0

Ich habe meine Frage aktualisiert –

+0

Es funktioniert alles gut bei loaclhost, aber bei LAN nicht so gut. –

Antwort

0

Wie groß ist Ihre Datei senden? Vielleicht wird es genug sein WebClient.DownloadDataAsync(...)?

UPDATED Wenn die Datei über 100 MB ist mit einfachem WebClient :)

 WebClient wc = new WebClient(); 
     wc.DownloadDataCompleted += new DownloadDataCompletedEventHandler(OnDownloadDataCompleted); 
     wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(OnDownloadProgressChanged); 
     wc.DownloadDataAsync(new Uri("http://www.xxxx.com/t.tar.gz")); 
+0

Ich bin schwer zu sagen. aber ich denke 10MB> –

0

TCP wird einen Teil der Daten zu einem Zeitpunkt erhalten - es wird keine Daten verlieren, aber wenn Sie sorgen nicht für die Tatsache ist, dass Daten in Pakete verschüttet werden und nacheinander ankommen und (oft) nicht als eine große "Datei", dann hören Sie vielleicht nicht auf den Rest der Daten zu - das wird so aussehen, als würden Daten fehlen, aber Wirklich ist es der Code, der den Rest ignoriert, nachdem das erste Paket empfangen worden ist. Nur weil du es in einem Loch sednest, bedeutet das nicht, dass es in einem Klumpen ankommen wird.

Es gibt viele Beispiele von TCP-Server/Client-Anwendungen (und Chat-Anwendungen) in der wunderbaren Welt von Google, damit Sie Notizen vergleichen können - alternativ können Sie Ihren Code posten und wir können dann sehen, wo der Fehler liegt.

+0

Ich habe meine Frage aktualisiert –

6

Das ist das Problem:

networkStream.Read(PartData, 0, bytesToRead); 

Nie den Rückgabewert von Read ignorieren. Nie angenommen, dass ein einzelner Aufruf zum Lesen alle Daten lesen wird. Sie müssen eine Schleife durchlaufen und lesen, bis alles "in" ist. Die Anzahl der Aufrufe an Read, die zum Lesen aller Daten benötigt werden, steht in keinem Verhältnis zur Anzahl der Aufrufe an Write. TCP ist ein Stream Protokoll - behandeln Sie es so.

Es ist nicht klar, ob Sie genau wissen, wie viele Daten Sie erwarten zu lesen - oder? Schließt der Server die Verbindung am Ende? Wenn ja, und wenn Sie mit .NET 4, dann kann man loswerden eine riesigen Menge dieses Codes erhalten:

using (Stream output = File.Create(filename)) 
{ 
    networkStream.CopyTo(output); 
}