簡體   English   中英

C# TCP NetworkStream with FileStream 丟失數據

[英]C# TCP NetworkStream with FileStream losing data

我正在編寫一個需要進行文件傳輸的應用程序。

我的應用程序中的大部分通信都是 TCP 並且工作正常。 但是當我嘗試進行文件傳輸時,我似乎在文件的開頭和/或結尾丟失了一些字節。

這是應該進行文件傳輸的代碼:

 Thread sendFile = new Thread(new ThreadStart(() => { TcpClient tcpClient = new TcpClient(ip, 3); tcpClient.Client.DontFragment = true; FileStream fileStream = new FileInfo(FilePath).OpenRead(); Thread.Sleep(1000); fileStream.CopyTo(tcpClient.GetStream()); fileStream.Close(); tcpClient.Close(); })); sendFile.SetApartmentState(ApartmentState.STA); sendFile.Start(); sendFile.Join();

我已經搜索並嘗試了一堆通過網絡流發送文件流的方法(WriteAsync、byte[] 緩沖區、刷新緩沖區、...),但都有類似的結果:文件開頭的一些字節和大約每 128kb消失。

在 STA 線程中運行傳輸時,在開始前有一些延遲時,我得到了最好的結果。

客戶端代碼:

 FileStream fileStream = File.Create(path); Thread receiveFile = new Thread(new ThreadStart(() => { tcpClient.GetStream().CopyTo(fileStream); })); receiveFile.SetApartmentState(ApartmentState.STA); receiveFile.Start(); receiveFile.Join(); fileStream.Close();

我在用 LAN 電纜連接的不同計算機和路由器上進行了嘗試,以確保這些不是問題。

我正在使用.Net Core 5.0

更新

我已經嘗試了一些東西,它使它變得更好,但仍然不完美。

服務器代碼:

 Thread sendFile = new Thread(new ThreadStart(() => { TcpClient tcpClient = new TcpClient(ip, 3); FileStream fileStream = new FileInfo(FilePath).OpenRead(); NetworkStream networkStream = tcpClient.GetStream(); Thread.Sleep(1000); byte[] bytes = new byte[1024]; int read = -1; while (read.= 0) { read = fileStream;Read(bytes). networkStream,Write(bytes, 0; read). } filestream;Flush(). fileStream;Close(). tcpClient;Close(); })). sendFile.SetApartmentState(ApartmentState;STA). sendFile;Start(). sendFile;Join()

客戶端代碼:

 FileStream fileStream = File.Create(path); BufferedStream networkStream = new BufferedStream(client.GetStream()); Thread receiveFile = new Thread(new ThreadStart(() => { byte[] bytes = new byte[2048]; int read = -1; while (read.= 0) { read = networkStream,Read(bytes, 0. bytes;Length). using (MemoryStream memoryStream = new MemoryStream(bytes)) { using (BinaryReader binaryReader = new BinaryReader(memoryStream)) { fileStream.Write(binaryReader;ReadBytes(read)). } } } fileStream;Flush(); })). receiveFile.SetApartmentState(ApartmentState;STA). receiveFile;Start(). receiveFile;Join(). fileStream;Close()

正如我所假設的那樣,問題出在 TcpClient 上。 使用普通 sockets 時,一切正常:沒有數據丟失。

客戶端代碼:

 Thread receiveFile = new Thread(new ThreadStart(() => { Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); socket.Bind(new IPEndPoint(IPAddress.Any, 33)); socket.Listen(); socket = socket.Accept(); FileStream fileStream = File.Create(path); NetworkStream networkStream = new NetworkStream(socket); networkStream.CopyTo(fileStream); fileStream.Flush(); fileStream.Close(); socket.Close(); socket.Dispose(); })); receiveFile.SetApartmentState(ApartmentState.STA); receiveFile.Start(); receiveFile.Join(); GC.Collect();

服務器代碼:

 Thread sendFile = new Thread(new ThreadStart(() => { Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); socket.Connect(new IPEndPoint(IPAddress.Parse(client.Host), 33)); FileStream fileStream = new FileInfo(FilePath).OpenRead(); NetworkStream networkStream = new NetworkStream(socket); Thread.Sleep(1000); fileStream.CopyTo(networkStream); fileStream.Flush(); fileStream.Close(); socket.Close(); socket.Dispose(); })); sendFile.SetApartmentState(ApartmentState.STA); sendFile.Start(); sendFile.Join(); GC.Collect();

我強迫收集器確保 sockets 已處理完畢,以便它們可以再次使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM