1

我需要有一个文件服务器作为桌面应用程序的一部分,它应该尽可能快地响应文件传输请求(来自远程客户端,通常位于同一个 LAN 上)。小文件会有很多文件请求。服务器应该能够提供上传和下载服务。

我不拘泥于任何特定的技术,所以我对任何编程语言、工具包、库都持开放态度,只要它们可以在 Windows 上运行。

我最初的想法是使用 Windows 套接字实现 C/C++ 或使用 Boost(asio 等)等库提供的服务。我也想到了 Erlang,但我必须学习,因此性能优势应该证明由于必须学习该语言而增加的开发时间是合理的。

后期编辑:我很欣赏那些说使用 FTP 或 HTTP 或基本上已经创建的任何东西的答案,但考虑到你仍然想从头开始编写一个,你会怎么做?

4

8 回答 8

5

为什么不直接使用FTP呢?您应该能够找到任何语言的适当服务器实现,以及客户端访问库。

这听起来像是很多轮子改造。诚然,FTP 并不理想,并且有一些奇怪的地方,但是……它就在那里,它是标准的、众所周知的,并且已经非常广泛地实施。

于 2009-04-17T11:54:55.173 回答
3

对于小文件的频繁上传,最快的方法是实现自己的专有协议,但这需要大量的工作——而且它也是非标准的,这意味着未来的集成将很困难,除非你能够实现您将支持的任何客户端中的协议。如果您仍然选择这样做,这是我对简单协议的建议:

  1. 命令:1 个字节来标识将要做什么:(0x01 表示上传请求,0x02 表示下载请求,0x11 表示上传响应,0x12 表示下载响应等)。
  2. 文件名:可以是固定大小或以字节为前缀长度(假设名称小于255字节)
  3. 校验和,例如 MD5(如果上传请求或下载响应)
  4. 文件大小(如果上传请求或下载响应)
  5. 有效载荷(如果上传请求或下载响应)

这可以在一个简单的 TCP 套接字之上实现。您也可以使用 UDP,避免建立连接的成本,但在这种情况下,您必须处理重传控制。

在决定实现你自己的协议之前,先看看像 libcurl 这样的 HTTP 库,你可以让你的服务器使用标准的 HTTP 命令,比如 GET 来下载和 POST 来上传。这将节省大量工作,您将能够使用任何 Web 浏览器测试下载。

另一个提高性能的建议是使用文件存储库而不是文件系统,而是使用 SQLite 之类的东西。您可以创建一个表,其中包含一个用于文件名的 char 列和一个用于文件内容的 blob 列。由于 SQLite 是轻量级的并且可以进行有效的缓存,因此您大部分时间都可以避免磁盘访问开销。

我假设您不需要客户端身份验证。

最后:尽管 C++ 是您的首选,可以为您提供原始本机代码速度,但这很少是此类应用程序的主要瓶颈。很可能是磁盘访问和网络带宽。我之所以提到这一点,是因为在 Java 中,您可能能够用不到 100 行代码制作一个 servlet 来做完全相同的事情(使用 HTTP GET 进行下载和 POST 进行上传)。在这种情况下使用 Derby 而不是 SQLite,将该 servlet 放入任何容器(Tomcat、Glassfish 等)中,然后就完成了。

于 2009-04-17T14:28:36.037 回答
2

如果所有机器都在同一个 LAN 上的 Windows 上运行,那为什么还需要一台服务器呢?为什么不简单地使用 Windows 文件共享?

于 2009-04-17T11:56:56.243 回答
2

我建议不要使用 FTP、SFTP 或任何其他面向连接的技术。相反,请选择无连接协议或技术。

原因是,如果您需要上传或下载大量小文件,并且响应应该尽可能快,您希望避免建立和破坏连接的成本。

我建议您查看使用现有实现或实现自己的 HTTP 或 HTTPS 服务器/服务。

于 2009-04-17T12:01:19.027 回答
2

您的瓶颈可能来自以下来源之一:

  • 硬盘 I/O - WD velociraptor 应该具有大约 100MB/s 的随机访问速度。此外,重要的是您是否将其设置为 RAID0、1、5 或其他。有些人读得快,写得慢。权衡取舍。

  • 网络 I/O - 假设您在快速 RAID 设置中拥有最快的硬盘,除非您使用 Gbit I/O,否则您的网络将会很慢。如果您的管道很大,您仍然需要为其提供数据。

  • 内存缓存 - 内存中文件系统缓存需要足够大以缓冲所有网络 I/O,这样它就不会减慢您的速度。对于您正在查看的工作,这将需要大量内存。

  • 文件系统结构——假设你有千兆字节的内存,那么瓶颈很可能是你用于文件系统的数据结构。如果文件系统结构很麻烦,它会减慢你的速度。

假设所有其他问题都已解决,那么您是否担心您的应用程序本身。请注意,大多数瓶颈都超出了您的软件控制范围。因此,无论您是使用 C/C++ 编写代码还是使用特定的库,您仍然会受制于操作系统和硬件。

于 2009-04-17T13:40:25.560 回答
1

听起来您应该使用SFTP (SSH) 服务器,它是防火墙/NAT 安全、可靠的,并且已经可以满足您的需求等等。您还可以使用 SAMBA 或 windows 文件共享来实现更简单的实现。

于 2009-04-17T11:56:25.713 回答
1

为什么不使用现有的东西,例如普通的 Web 服务器可以非常快速地处理大量小文件(图像)。

许多人已经花时间优化代码。

第二个好处是传输是通过已建立的协议 HTTP 完成的。如果您需要更高的安全性,可以轻松切换到 SSL。

对于上传,脚本或自定义模块也没有问题 - 使用相同的方法您也可以添加授权。

只要您不需要动态查找文件,我想这将是最好的解决方案之一。

于 2009-04-17T12:00:24.193 回答
0

它是现有桌面应用程序的新部分吗?服务器的目标是什么?它是否保护上传/下载的文件并提供身份验证和/或授权?它是否为要存储的上传内容提供某种结构?

一种选择可能是在机器上安装 Apache HTTP Server 并通过它提供文件。使用 POST 上传,使用 GET 下载。

如果客户端在 LAN 内,您是否可以不共享驱动器?

于 2009-04-17T12:10:41.983 回答