2016-03-14 4 views
0

У меня возникла странная проблема. Когда я пытаюсь отправить файл через TCP-сокет, первые 4 байта отложенной информации отключаются.NetworkStream отключает первые 4 байта при чтении

Это отправляет и получает коды.

стороне клиента

for (var i = 0; i < fileContentByte.Length; i += buffer.Length) 
{ 
    var size = (i + buffer.Length > fileContentByte.Length) ? fileContentByte.Length - i : buffer.Length; 
    clientSocket.Write(fileContentByte, i, size); 
} 

стороне сервера

using(var file = File.Create("C:\\test\\"+fileName.Substring(0, fileName.IndexOf('\0')))) 
while(bytesReceived < numberOfBytes && (count = clientStream.Read(buffer, 0, buffer.Length)) > 0) 
{ 
    file.Write(buffer, 0, count); 
    bytesReceived += count; 
} 

Вот ссылка на полный код - http://pastebin.com/VwTgTxgb

ответ

1

Вы делаете что-то очень странно здесь.

Прежде всего, поиск имени файла может быть значительно упрощен до Path.GetFileName().

Во-вторых, вы уверены, что ASCII хватит?

В-третьих, чтение всего файла в память является ОК-иш для проекта концепции доказательств, но будьте готовы к переключению на потоковые операции.

В-четвертых, ваш протокол несколько воинственный. При отправке полезной нагрузки с переменным размером необходимо сначала сообщить получающей стороне, сколько байтов вы собираетесь отправить. Это именно то, что вы не делаете при отправке имени файла.

Вот отрывок, чтобы вы начали:

using System; 
using System.Diagnostics; 
using System.IO; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 

namespace FolderSync 
{ 
    class Program 
    { 
     static void Main() 
     { 
      var server = new Server(); 
      server.Start(); 

      new Client().TransmitFile(
       new IPEndPoint(IPAddress.Loopback, 35434), 
       @"f:\downloads\ubuntu-14.04.3-desktop-amd64.iso"); 

      Console.ReadLine(); 

      server.Stop(); 
     } 
    } 

    class Server 
    { 
     private readonly TcpListener tcpListener; 

     public Server() 
     { 
      tcpListener = new TcpListener(IPAddress.Loopback, 35434); 
     } 

     public void Start() 
     { 
      tcpListener.Start(); 
      tcpListener.BeginAcceptTcpClient(AcceptTcpClientCallback, null); 
     } 

     public void Stop() 
     { 
      tcpListener.Stop(); 
     } 

     private void AcceptTcpClientCallback(IAsyncResult asyncResult) 
     { 
      // 
      // Big fat warning: http://stackoverflow.com/a/1230266/60188 

      tcpListener.BeginAcceptTcpClient(AcceptTcpClientCallback, null); 

      using(var tcpClient = tcpListener.EndAcceptTcpClient(asyncResult)) 
      using(var networkStream = tcpClient.GetStream()) 
      using(var binaryReader = new BinaryReader(networkStream, Encoding.UTF8)) 
      { 
       var fileName = binaryReader.ReadString(); 
       var length = binaryReader.ReadInt64(); 

       var mib = length/1024.0/1024.0; 
       Console.WriteLine("Receiving '{0}' ({1:N1} MiB)", fileName, mib); 

       var stopwatch = Stopwatch.StartNew(); 

       var fullFilePath = Path.Combine(Path.GetTempPath(), fileName); 
       using(var fileStream = File.Create(fullFilePath)) 
        networkStream.CopyTo(fileStream); 

       var elapsed = stopwatch.Elapsed; 

       Console.WriteLine("Received in {0} ({1:N1} MiB/sec)", 
        elapsed, mib/elapsed.TotalSeconds); 
      } 
     } 
    } 

    class Client 
    { 
     public void TransmitFile(IPEndPoint endPoint, string fileFullPath) 
     { 
      if(!File.Exists(fileFullPath)) return; 

      using(var tcpClient = new TcpClient()) 
      { 
       tcpClient.Connect(endPoint); 

       using(var networkStream = tcpClient.GetStream()) 
       using(var binaryWriter = new BinaryWriter(networkStream, Encoding.UTF8)) 
       { 
        var fileName = Path.GetFileName(fileFullPath); 
        Debug.Assert(fileName != null, "fileName != null"); 

        // 
        // BinaryWriter.Write(string) does length-prefixing automatically 
        binaryWriter.Write(fileName); 

        using(var fileStream = File.OpenRead(fileFullPath)) 
        { 
         binaryWriter.Write(fileStream.Length); 
         fileStream.CopyTo(networkStream); 
        } 
       } 
      } 
     } 
    } 
} 
+0

Спасибо большое! Это работает с BinaryReader. Это просто простой пример теста, не работающий прототип, но спасибо за то, что он указал на слабые места, что было действительно полезно. – Rincew1nd

Смежные вопросы