2014-05-17 4 views
1

В настоящее время я работаю над программой на C#, которая позволяет пользователю отправлять файл по сети и собирать его на другом конце. Все работает отлично, за исключением того, что несколько байтов были помещены в место назначения, оставляя его как не совсем тот же файл, с которого он начинался. (Коррупция изображений, например). Редактировать: По крайней мере, когда это на моем компьютере, я заметил, что ошибка может быть решена, если клиент ждет одну секунду, прежде чем начать читать из потока, это дает мне представление о том, что клиент время от времени попадает в конец потока и вместо этого читает что-то другое. Любая идея, как исправить это лучше, чем просто ждать второй, как с другими компьютерами, я не знаю, будет ли это работать. код для моего сервера выглядит следующим образом:TCP File Transfer - ошибка нескольких байтов

TcpListener listener = new TcpListener(13); 
     listener.Start(); 
     FileStream inputStream = File.OpenRead(loadLocation.Text);//loadLocation being a text box with the file path 
     FileInfo f = new FileInfo(loadLocation.Text); 
     int size = unchecked((int)f.Length);//Get's the file size in Bytes 
     int csize = size/4096;//Get's the size in chunks of 4kb; 

      statusLabel.Text = "Waiting for connection..."; 
      TcpClient client = listener.AcceptTcpClient(); 
      statusLabel.Text = "Connection accepted."; 
      NetworkStream ns = client.GetStream(); 
      byte[] byteSize = BitConverter.GetBytes(size);//Sends the number of bytes to expect over the network 
      try 
      { 
       ns.Write(byteSize, 0, byteSize.Length); 
       byte[] temp = new byte[4096]; 
       for (int i = 0; i < csize; i++) 
       { 
        inputStream.Read(temp, 0, 4096); 
        ns.Write(temp, 0, 4096); 
       } 
       byte[] end = new byte[size % 4096]; 
       inputStream.Read(end, 0, size % 4096); 
       ns.Write(end, 0, size % 4096); 
       ns.Close(); 
       inputStream.Close(); 
       client.Close(); 
       done = true; 
       statusLabel.Text = "DONE!"; 
      } 
      catch (Exception a) 
      { 
       Console.WriteLine(a.ToString()); 
      } 
     listener.Stop(); 

клиентский код выглядит следующим образом:

try 
     { 
      FileStream outputStream = File.OpenWrite(saveLocation.Text); 
      TcpClient client = new TcpClient("127.0.0.1", 13); 

      NetworkStream ns = client.GetStream(); 

      byte[] byteTime = new byte[sizeof(int)]; 
      int bytesRead = ns.Read(byteTime, 0, sizeof(int)); 
      int size; 
      size = BitConverter.ToInt32(byteTime, 0); 
      int csize = size/4096; 
      byte[] temp = new byte[4096]; 
      for (int i = 0; i < csize; i++) 
      { 
       ns.Read(temp, 0, 4096); 
       outputStream.Write(temp, 0, 4096); 
      } 
      byte[] end = new byte[size % 4096]; 
      ns.Read(end, 0, size % 4096); 
      outputStream.Write(end, 0, size % 4096); 
      ns.Close(); 
      outputStream.Close(); 
      client.Close(); 
      statusLabel.Text = "DONE!"; 

     } 
     catch (Exception a) 
     { 
      Console.WriteLine(a.ToString()); 
     } 

Я знаю, что TCP гарантирует порядок доставки и как таковой, я понятия не имею, что может быть, возможно, вызывая проблему с выходным файлом. Другая заметка заслуживает того, что каждый раз, коррупция несколько отличается, например, при передаче изображения будет большой знак в другой точке изображения.

ответ

1

Ваш код должен учитывать, что NetworkStream (и большинство TCP sockets в целом) необязательно возвращает полное количество первоначально запрошенных байтов.

Microsoft writes:

операция чтения считывает столько данных, сколько есть в наличии, до числа байтов, заданное параметром размера.

Добавить внешний цикл вокруг ваших операций чтения, чтобы гарантировать, что буфер фактически заполнен. Также было бы целесообразно сделать еще несколько ошибок.

Возможно, вы можете получить вдохновение от аналогичного question+answer. Он показывает, как может выглядеть такой внешний цикл.

+0

Большое спасибо, я бы проголосовал за ваш ответ, если бы у меня была большая репутация. – Jack