使用 .NET 在慢速网络上移动不同大小的文件的最佳方法
我正在构建一个 .NET 远程客户端/服务器,它将传输数千个不同大小的文件(从几个字节到数百 MB),并且我希望获得一些有关实现此目的的最佳方法的反馈。在我看来,有几个选项:
- 将整个文件序列化到我的远程对象中并立即传输,无论大小如何。这可能是最快的,但是传输过程中出现故障需要重新传输整个文件,并且无法恢复。
- 如果文件大小大于某些小文件(例如 4KB),请将其分解为 4KB 块并将其远程化,然后在服务器上重新组装。除了这一点的复杂性之外,由于持续的往返和确认,它的速度也更慢,尽管任何一个部分的失败都不会浪费太多时间。
- 在我的应用程序中包括诸如 FTP 或 SFTP 服务器之类的东西 - 客户端将通知服务器它正在开始使用远程处理,上传文件,然后使用远程处理来通知完成。我希望将所有内容都包含在我的应用程序中,而不需要单独的 FTP 服务,但如果需要,我愿意接受此选项。
- 使用某种指定的 TCP 连接或 WPF 或其他一些传输方法,这些方法是为处理故障而构建的,或者能够执行某种检查点/恢复。
- 我还缺少其他人吗?
最灵活/可靠的传输方法是什么?我不太关心速度,但更关心可靠性 - 我希望文件能够移动,即使速度很慢。由于客户端和服务器将是多线程的,因此如果连接允许,我可以同时传输多个文件。
感谢您的反馈 - 我将提供赏金以获得一些关于人们实现这一目标的方法的建议。
I'm building a .NET remoting client/server that will be transmitting thousands of files, of varying sizes (everything from a few bytes to hundreds of MB), and I'd like some feedback on the best method for achieving this. As I see it, there are a couple of options:
- Serialize the entire file into my remoting object and transmit at all at once, regardless of size. This would probably be the fastest, but a failure during transmission requires that the whole file be re-transmitted, with no way to resume.
- If the file size is larger than something small (like 4KB), break it into 4KB chunks and remote those, re-assembling on the server. In addition to the complexity of this, it's slower because of continued round-trips and acknowledgements, though a failure of any one piece doesn't waste much time.
- Including something like an FTP or SFTP server with my application - the client will notify the server that it's starting using remoting, upload the file, then use remoting to notify of completion. I'd like to contain everything in my app instead of requiring a separate FTP service, but I'm open to this option if it's needed.
- Use some kind of stated TCP connection or WPF or some other transmission method that's built to handle the failures or is capable of doing some kind of checkpoint/resume.
- Any others I'm missing?
What's the most flexible/reliable transmission method? I'm not that concerned about speed, but more about reliability - I want the file to move, even if it's slowly. Since the client and server will be multi-threaded, I can transmit multiple files at the same time if the connection allows it.
Thanks for your feedback - I'll throw in a bounty to get some recommendations on ways people would accomplish this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
BITS(后台智能传输服务)是一个很好的解决方案。它拥有多年的经验,
一些起点是
BITS (background Intelligent Transfer Service) is a good solution. It has years of experience built in
Some starting points are
尽管 calmh 确实回答了您从 OSI 第 4 层生活中提出的问题,但我觉得您更多地关注问题中的应用程序层。 TCP 确实可以处理网络生活中的所有问题,包括延迟、传输窗口等。然而,它并不能直接确定如果用户提前结束下载会话然后决定稍后从中断处继续下载会发生什么。
为了从不同的角度回答您的问题,我绝对建议将文件分成多个部分,并为所有连接建立索引,无论速度如何。下载整个文件后,可以在客户端上重新组装它们。这允许用户暂停下载会话并恢复。
至于确定速度,可能有预先构建的方法来执行此操作,但您可以使用的一种方法是构建自己的速度测试:
向客户端发送 1 MB(上传)并让它在收到后发送响应。 1100除以从客户端获取响应所花费的时间,就是客户端从服务器下载所需的KB/s。反之亦然,测试客户端上传。
就传输而言,我建议利用现有技术。 SFTP 支持经过身份验证的加密数据传输。它基本上是 FTP,但通过 SSH。应该有可用的 API 来与之交互。
顺便说一句,我从来没有做过你所说的任何事情,但希望我的想法至少能给你提供一些可供考虑的选择。
Although calmh does answer the question you're asking from the OSI layer 4 side of life, I feel more like you're looking more at the application tiers in your question. TCP definitely does handle everything ranging from latency, transmission windows, etc on the networking side of life. However, it does not directly determine what happens if a user ends a download session prematurely and then decides to pick it up later where they left off.
To answer your question from a different angle, I would definitely recommend chunking the file into sections and indexing them for all connections, regardless of the speed. They can then be re-assembled again on the client once the entire file is downloaded. This allows the user to pause download sessions and resume.
As far as determining the speed, there may be methods pre-built to do this, but one method you could use is just build your own speed test:
Send 1 MB to the client (upload) and have it send a response once received. 1100 divided by the time it took to get the response back from client, is the KB/s it takes the client to download from the server. And vise versa to test upload from the client.
As far as transmitting, I would recommend utilizing existing technologies. SFTP supports authenticated encrypted data transfer. It is basically FTP, but over SSH. There should be APIs available somewhere for interacting with this.
On a side note, I have never done anything to the extent that you talk about, but hopefully my ideas at least give you a couple options to consider.
这就是 TCP 本身的用途,并在数十年或艰苦的测试中进行了调整。远程处理适用于小型 RPC 调用,而不是大型文件传输。您应该简单地使用 TCP 套接字来传输数据,并让下层协议担心延迟、传输窗口、MTU 等。
This is what TCP itself is made for, and tuned for during decades or hard testing. Remoting is made for small RPC calls, not large file transfers. You should simply use a TCP socket for transmitting the data, and let the lower layer protocols worry about latency, transmission windows, MTU, etc.