TcpListener 从 Tcp 客户端接收块文件

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

我有一个带有服务器和客户端的 C# 项目,使用

TcpListener
TcpClient
,我想让客户端向服务器发送文件。

我是网络新手,但据我所知,最好的方法是让客户端首先将文件的大小发送到服务器,这样它就可以准备接收正确的字节数,然后客户端发送文件,服务器不是一次性接收文件,而是分块接收。

我有这个代码:

客户:

 byte[] fileNameByte = Encoding.UTF8.GetBytes(fileName);
 byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
 byte[] fileData = File.ReadAllBytes(fileName);
 byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];

 fileNameLen.CopyTo(clientData, 0);
 fileNameByte.CopyTo(clientData, 4);
 fileData.CopyTo(clientData, 4 + fileNameByte.Length);

 StreamCommands.Write(clientData, 0, clientData.Length);

服务器:

byte[] fileData = new byte[999999999];

int recievedBytesLen = await Task.Run(() => currentClient.StreamCommands.Read(fileData, 0, fileData.Length));
int fileNameLen = BitConverter.ToInt32(fileData, 0);
string fileName = Encoding.UTF8.GetString(fileData, 4, fileNameLen);

int st = fileName.LastIndexOf("\\") + 1;
int en = fileName.Length;
string fname = fileName.Substring(st, en - st);

BinaryWriter bWrite = new BinaryWriter(File.Open(recievedFilePath+fname, FileMode.Create));
bWrite.Write(fileData, 4 + fileNameLen, recievedBytesLen - 4 - fileNameLen);
bWrite.Close();

这段代码确实有效,我可以一次发送一个小文件,但我不想仅限于小文件,而且我知道以块的形式接收数据会更有效,所以我想知道我会怎么做关于在我的代码中实现它。

c# networking tcp tcpclient tcplistener
1个回答
0
投票

我强烈建议您使用更高级别的网络堆栈;例如,您可以嵌入 ASP.NET Core 服务器,然后使用标准 HTTP 文件上传。

如果您确实需要 TCP/IP,那么您需要重新审视您的协议,然后开始使用循环。目前的协议发送文件名的长度,然后发送文件名,然后发送文件数据。缺少的是文件数据的长度;您应该发送文件名的长度、文件名、文件数据的长度和文件数据。

然后,在接收端,需要从套接字连接中重复读取字节,直到有足够的文件名长度,然后为文件名分配空间,然后重复读取字节,直到有整个文件名,然后重复读取字节,直到有足够的文件数据长度,然后为文件数据分配空间,然后重复读取字节,直到拥有整个文件数据。

或者,您可以为整个消息使用单个长度前缀,但您仍然需要字段的长度前缀来区分文件名和文件数据。

我的博客上有一些代码可以为每条消息添加前缀

© www.soinside.com 2019 - 2024. All rights reserved.