使用c#中的流将文件从服务器传输到客户端时数据丢失

Posted

技术标签:

【中文标题】使用c#中的流将文件从服务器传输到客户端时数据丢失【英文标题】:data loss when file is transfer from server to client using stream in c# 【发布时间】:2011-04-13 04:14:54 【问题描述】:

服务器端

stream.BeginWrite(clientData, 0, clientData.Length, 
       new AsyncCallback(CompleteWrite), stream);

客户端

int tot = s.Read(clientData, 0, clientData.Length);

我用过 TCPClient、TCPlistener 类

clientData是一个字节数组。ClientData在服务器端的大小是2682。我使用NetworkStream类来写数据

但在客户端接收到的数据仅包含 1642 字节。我使用流类在客户端读取数据

怎么了?

【问题讨论】:

有两种方法可以解决这个问题先发送数据大小并读取(查看BitConverter),或者读取直到读取0字节(0 = EOF) 我已经检查了数据的大小。我使用 ReadWholeArray() 方法读取流,直到发送数据的大小,但在读取 1642 字节后,下一次调用读取下一个剩余数据被卡住了。然后程序没有响应 那么你应该仔细检查你是否真的在服务器端发送了所有 2682 字节。您是否通过 CompleteWrite 方法调用 stream.EndWrite 【参考方案1】:

允许 Read 方法返回的字节数少于您请求的字节数。您需要反复调用 Read,直到收到所需的字节数。

【讨论】:

【参考方案2】:

使用此方法从流中正确读取:

public static void ReadWholeArray (Stream stream, byte[] data)

int offset=0;
int remaining = data.Length;
while (remaining > 0)

    int read = stream.Read(data, offset, remaining);
    if (read <= 0)
        throw new EndOfStreamException 
            (String.Format("End of stream reached with 0 bytes left to read", remaining));
    remaining -= read;
    offset += read;
 

您可能希望先将文件的长度写入流中(例如 int) 例如,

服务器端:

server.Write(clientData.Length)
server.Write(clientData);

客户端:

 byte[] size = new byte[4];                
 ReadWholeArray(stream, size);
 int fileSize = BitConverter.ToInt32(size, 0);
 byte[] fileBytes = new byte[fileSize];
 ReadWholeArray(stream, fileBytes);

有关从流中读取的更多信息,请参阅 http://www.yoda.arachsys.com/csharp/readbinary.html

【讨论】:

在服务器端编码中,对象服务器是哪个类?因为我将 NetworkStream 类对象与方法 Write 用于此代码,它告诉“方法'Write'没有重载需要'1'参数”。所以请告诉服务器对象属于哪个类 只需像在原始代码示例中一样使用 BeginWrite,或者使用 Write(clientData, 0, clientData.Length),假设 clientData 是您的 byte[] 数组

以上是关于使用c#中的流将文件从服务器传输到客户端时数据丢失的主要内容,如果未能解决你的问题,请参考以下文章

在tcp从python服务器传输到c#客户端期间丢失数据

CGBTN2107-DAY13总结复习

如何将 MJPEG 流保存到磁盘(C# .NET)?

将实时视频从我的 c# 应用程序流式传输到 ASP.NET 网页

Unity使用webSocket与服务器通信——C#服务端(Fleck)与Unity客户端( NativeWebSocket)传输多种数据数据

前几条消息在传输到离线的 mqtt 客户端时丢失