在 C# 中通过 Socket 传输文件

问题描述 投票:0回答:0

我已经设法编写代码在两台 PC 之间通过 C# 中的 Socket 传输文件。

这几天一直在摸不着头脑,想找出问题所在

这似乎只有在我调试并跨过所有内容时才有效。

以下是我的代码的相关混合版本。

服务器端:

    internal async Task TransferProc() 
     { 
         
         while (Index < fileSize) 
         { 
             
  
          
             try 
             {
                 FS!.Position = Index; 
  
                 var read = await FS.ReadAsync(file_buffer, 0, file_buffer.Length); 
                 await FS.FlushAsync(); 
                 using var ms = new MemoryStream(); 
                 using var pw = new BinaryWriter(ms); 
  
                 { 


               If(!isFileNameSent)
                 {
            FS = new FileStream(somefile, FileMode.OpenOrCreate);
               pw.Write(filename);
               pw.Write(fileSize); 
               isFileNameSent= true;

                 }
                     
                     pw.Write(file_buffer); 
  
                 
                     Transferred += read; 
                     Index += read; 
  
                    
                    await SendData(ms.ToArray())
                 } 
             } 
             catch (Exception) 
             { 
                 throw; 
             } 
           
         } 
         //Cleanup Code
     }


     var SocketWriteStream = _baseSocket.OutputStream.AsStreamForWrite(); 
     var SocketReadStream = _baseSocket.InputStream.AsStreamForRead();

public Task SendData(byte[] data) 
     { 
         
         lock (lockObj) // necessary as method is called by multiple objects to transfer data.
         { 
             try 
             { 
                 
                 //Send the size of the data. 
  
                 SocketWriteStream!.WriteAsync(BitConverter.GetBytes(data!.Length), 0, 4); 
  
                 //And then the actual data. 
  
                 SocketWriteStream.WriteAsync(data, 0, data.Length); 
                 SocketWriteStream.FlushAsync(); 
             } 
             catch (Exception) 
             { 
                 
                 throw; 
             } 
         } 
     }

现在在客户端:

public async Task<bool> StartClient() 
     { 
         while (true) 
         { 
             try 
             { 
                 var bytesRead = await SocketReadStream!.ReadAsync(_buffer!, 0, 4); 
  
                 if (bytesRead > 0) 
                 { 
                     var size = BitConverter.ToInt32(_buffer!, 0); 
                     
                     if (size > _buffer.Length) 
                     { 
                         _buffer = new byte[size]; 
                         Debug.WriteLine($"Buffer size {_buffer.Length} and size {size}"); 
                     } 
                     var read = await SocketReadStream.ReadAsync(_buffer!, 0, size); //EXCEPTION A
                     await SocketReadStream.FlushAsync(); 
                    

        using var pr = new BinaryReader(new MemoryStream(_buffer )); 


        If(!isFileNameRecd)
           { 
   var fileName = pr.ReadString(); 
        
      var length = pr.ReadInt64();

      var path= Path.Combine(someFolder, fileName)

      FS = new FileStream(path, FileMode.OpenOrCreate); //EXCEPTION B
isFileNameRecd= true;

}
                     
                    

                    var bytes = pr.ReadBytes(size);

        await FS.WriteAsync(bytes, 0, bytes.Length); 
         await FS.FlushAsync();

  
               
                 } 
                 else 
                 { 
                    
                     Debug.WriteLine("Run Closed"); 
  
                
                 } 
             } 
             catch (Exception e) 
             { 
                 Debug.WriteLine($"Socket was closed! due to {e.Message} and {e.InnerException?.Message}"); 
                 
                 throw; 
             } 
         } 
     }

现在我面临如下两个例外,

异常 A:偏移量和长度超出数组范围或计数大于从索引到源集合末尾的元素数。

例外 B:找不到路径的一部分 PartialPathToFile.

我尝试过的:

如果我在异常 A 处使用断点进行调试并继续越过,我不会遇到任何问题,并且数据会完全完整地记录下来。

问题:

如果代码运行时没有任何断点,则随机出现异常 A 和 B。

不知何故,数据包 recd 的大小增加的方式超过了缓冲区。来自服务器的长度,这在客户端 ReadAsync 方法中最让我困扰。

注意事项:

从SSD读取数据,瞬间完成读取操作

考虑到其他文件元数据,我已经调整了两侧的缓冲区。

我在手机上输入了整个问题,所以请原谅格式和所有问题。

我还在学习编程。

c# sockets networking stream filestream
© www.soinside.com 2019 - 2024. All rights reserved.