2012-04-23 4 views
0

私はtcpソケットを使ってファイル転送アプリケーション[server-client]を持っています。ファイル転送を修正する方法、受信したファイルが壊れていますか?

1つのファイルを送信すると成功しますが、多くのファイルを含むフォルダを送信すると、受信したファイルが破損し、クライアントからの送信ファイルとサーバーからの受信ファイルのサイズが同じになります同じバイト数)。

enter image description here

サーバー:

private void ReceiveX(Socket client, string destPath, long size, int bufferSize) 
    { 
     using (Stream stream = File.Create(destPath)) 
     { 
      byte[] buffer = new byte[bufferSize]; 
      long sum = 0; 
      int count = 0; 
      do 
      { 
       count = client.Receive(buffer, 0, buffer.Length, SocketFlags.None); 
       stream.Write(buffer, 0, count); 
       sum += count; 
      } while (sum < size); 
     } 
    } 

クライアント:

private void SendX(Socket socket, string filePath, long size, int bufferSize, DoWorkEventArgs e) 
    { 
     using (Stream stream = File.OpenRead(filePath)) 
     { 
      byte[] buffer = new byte[bufferSize]; 
      long sum = 0; 
      int count = 0; 
      do 
      { 
       if (worker.CancellationPending) 
       { 
        e.Cancel = true; 
        return; 
       } 
       count = stream.Read(buffer, 0, buffer.Length); 
       socket.Send(buffer, 0, count, SocketFlags.None); 
       sum += count; 
       worker.ReportProgress((int)((sum * 100)/size)); 
      } while (sum < size); 
     } 
    } 

bufferSizeのは、クライアントとサーバー
の両方に[* 1024年4]で任意のコードが間違ってあります上記?

クライアント:ファイルを送信するには、フォルダの上にここに私のループ:

private void SendDir(string path, int bufferSize, DoWorkEventArgs e) 
    { 
     using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) 
     { 
      IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0); 
      listener.Bind(endpoint); 
      listener.Listen(1); 
      client.ReceiveFolder((IPEndPoint)listener.LocalEndPoint, fileList, Path.Combine(currAddress,Path.GetFileName(path)),bufferSize); 
      Socket socket = listener.Accept(); 
      int count = 0; 
    foreach (_File file in fileList) 
      { 
       if (worker.CancellationPending) 
       { 
        e.Cancel = true; 
        return; 
       } 
       Console.WriteLine(++count); 
       SendX(socket, file.Path, file.Size, bufferSize, e); 
      } 
      socket.Dispose(); 
    } 

サーバー、前のサーバから受信したlist<_File>内のファイルをループ、それはファイルの情報(名前、パス、サイズ)が含まれていそのクライアントは次のように送信します:

private void ReceiveFolderTh(IPEndPoint endpoint, List<_File> Files, string destDir, int bufferSize) 
    { 
     Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     client.Connect(IPAddress.Parse("127.0.0.1"), endpoint.Port); 
     foreach (_File file in Files) 
     { 
      Directory.CreateDirectory(destDir + Path.GetDirectoryName(file.Name)); 
      ReceiveX(client, destDir + file.Name, file.Size, bufferSize); 
     } 
     client.Dispose(); 
    } 

どのように修正できますか?

答えて

0

ファイル間の明確な隔たりがないため、クライアントが最初のファイルに多くのデータを受信して​​いる可能性があります。あなたの受信コードは次のとおりです。あなたはいつもバイト(あなたが4096であると言う)buffer.Lengthまで受信

do 
{ 
    count = client.Receive(buffer, 0, buffer.Length, SocketFlags.None); 
    stream.Write(buffer, 0, count); 
    sum += count; 
} while (sum < size); 

。したがって、最初のファイルの長さが100バイトで次のファイルの長さが5,000バイトの場合、サーバーが4,096バイトのパケットを送信している可能性があります。コードは最初のファイルに忠実に格納されて格納されます。

電話で受信するバイト数をclient.Receiveに変更する必要があります。一つのファイルの終わりを超えて、次の1の開始に読んでからあなたを防ぐことができます

int bytesToReceive = Math.Min(buffer.Length, size - sum); 
count = client.Receive(buffer, 0, bytesToReceive, SocketFlags.None); 

:ような何か。

+0

私はすでにこのように解決しています。クライアント: '{Send {SendFile} finally {socket.Receive(new byte [1]、SocketFlags.None); } 'とサーバー:' {ReceiveFile} finally {client.Send(新しいバイト[1]、SocketFlags.None); } '、クライアントはサーバがバイトを送るまで待つでしょうが、あなたは良い方法です!どちらが速いの? –

+0

私のアプローチはやや速くなければなりません。 –

関連する問題