C#TCP NetworkStream带有文件流丢失数据
我正在编程一个需要进行文件传输的应用程序。
我应用程序中的大多数通信都是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 [] buffer [buffer,flush the Buffers ,, ...)类似的结果:文件开头的某些字节,每128kb大约消失。
在启动之前,我会以一定的延迟运行传输时,我得到了最好的结果。
客户端代码:
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
Update
我已经尝试了一些事情,但它使它变得更好,但仍然不完美。
服务器代码:
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();
I'm programing an application where I need to make file transfers.
Most of the communication in my application is TCP and works just fine. But when I try to do a file transfer, I seem to lose some bytes at the start and/or end of the file.
Here is the piece of code that is supposed to do the file transfer:
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();
I have searched and tried a bunch of methodes of sending a filestream through a networkstream (WriteAsync, byte[] buffer, flushing the buffers,...) but all had similar results: some bytes at the start of the file and about every 128kb disappear.
I got the best results when running the transfer in a STA thread with some delay before starting.
Client code:
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();
I tried it on different computers and routers connected with LAN cables to make sure those weren't the problems.
I'm using .Net Core 5.0
Update
I've tried a few things and it made it better, but still not perfect.
Server code:
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();
Client code:
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();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正如我认为问题所在的TCPCLIENT上。使用普通插座时,一切都应该按应有的作用:没有数据丢失。
客户端代码:
服务器代码:
我强迫收集器确保插座处置,因此可以再次使用它们。
As I had assumed the problem lies on the TcpClient. When using normal sockets everything works as it should: no data loss.
Client code:
Server code:
I forced the collector to make sure the sockets are disposed, so they can be used again.