Что бы вы использовали для реализации быстрого и легкого файлового сервера?

Мне необходимо иметь в составе настольного приложения файловый сервер, который должен максимально быстро отвечать на запросы на передачу файлов (от удаленных клиентов, обычно расположенных в той же локальной сети). Будет много файловых запросов для файлов небольшого размера. Сервер должен иметь возможность предоставлять как услуги загрузки, так и загрузки.

Я не привязан к какой-либо конкретной технологии, поэтому я открыт для любого языка программирования, наборов инструментов, библиотек, если они могут работать в Windows.

Вначале я решил использовать реализацию C/C++ с использованием Windows Sockets или использовать службы, предоставляемые такими библиотеками, как Boost (asio или тому подобное). Я также подумал об Erlang, но мне придется учиться, поэтому преимущества в производительности должны оправдывать увеличение времени разработки из-за необходимости изучать язык.

ПОСЛЕДНИЕ РЕДАКТИРОВАТЬ: Я ценю ответы, которые говорят использовать FTP или HTTP или в основном все, что уже было создано, но, учитывая, что вы все еще хотите написать один с нуля, что бы вы сделали?

8 ответов

Решение

Для частой загрузки небольших файлов самым быстрым способом было бы реализовать собственный проприетарный протокол, но это потребовало бы значительного объема работы - а также это было бы нестандартно, то есть интеграция в будущем будет затруднена, если вы не сможете реализовать ваш протокол в любом клиенте, которого вы будете поддерживать. Если вы все равно решите сделать это, я предлагаю простой протокол:

  1. Команда: 1 байт, чтобы определить, что будет сделано: (0x01 для запроса на загрузку, 0x02 для запроса на загрузку, 0x11 для ответа на загрузку, 0x12 для ответа на загрузку и т. Д.).
  2. Имя файла: может иметь фиксированный размер или префикс с байтом для длины (при условии, что имя меньше 255 байтов)
  3. Контрольная сумма, например, MD5 (если запрос на загрузку или ответ на загрузку)
  4. Размер файла (если запрос на загрузку или ответ на загрузку)
  5. полезная нагрузка (если запрос на загрузку или ответ на загрузку)

Это может быть реализовано поверх простого сокета TCP. Вы также можете использовать UDP, избегая затрат на установление соединения, но в этом случае вам приходится иметь дело с управлением повторной передачей.

Прежде чем принять решение о реализации вашего собственного протокола, взгляните на HTTP-библиотеки, такие как libcurl, вы можете заставить свой сервер использовать стандартные HTTP-команды, такие как GET для загрузки и POST для загрузки. Это сэкономит много работы, и вы сможете протестировать загрузку с помощью любого веб-браузера.

Еще одно предложение по повышению производительности - использовать в качестве хранилища файлов не файловую систему, а что-то вроде SQLite. Вы можете создать одну таблицу, содержащую один столбец char для имени файла и один столбец blob для содержимого файла. Поскольку SQLite легок и обеспечивает эффективное кэширование, большую часть времени вы избежите накладных расходов при доступе к диску.

Я предполагаю, что вам не нужна аутентификация клиента.

И наконец: хотя C++ - это ваше предпочтение предоставить вам сырую скорость собственного кода, редко это является основным узким местом в такого рода приложениях. Скорее всего, будет доступ к диску и пропускная способность сети. Я упоминаю об этом, потому что в Java вы, вероятно, сможете сделать сервлет, который будет делать то же самое (используя HTTP GET для загрузки и POST для загрузки) с менее чем 100 строками кода. В этом случае используйте Derby вместо SQLite, поместите этот сервлет в любой контейнер (Tomcat, Glassfish и т. Д.), И все готово.

Почему бы просто не пойти с FTP? Вы должны быть в состоянии найти подходящую реализацию сервера на любом языке, а также библиотеки клиентского доступа.

Звучит как переизобретение колес. Конечно, FTP не идеален и имеет несколько странных мест, но... он есть, он стандартный, хорошо известный и уже очень широко реализованный.

Ваши узкие места могут исходить из одного из следующих источников:

  • Ввод / вывод жесткого диска. Предполагается, что скорость WD Velociraptor составляет около 100 МБ / с. Кроме того, важно, чтобы вы установили его как RAID0,1,5 или что-то еще. Некоторые читают быстро, но пишут медленно. Компромиссы.

  • Сетевой ввод / вывод - при условии, что у вас самые быстрые жесткие диски в быстрой установке RAID, если вы не используете Gbit I/O, ваша сеть будет работать медленно. Если ваши каналы большие, вам все равно нужно предоставить данные.

  • Кэш-память. Кэш-память файловой системы в памяти должна быть достаточно большой, чтобы буферизовать весь сетевой ввод-вывод, чтобы он не замедлял работу. Это потребует большого количества памяти для той работы, на которую вы смотрите.

  • Структура файловой системы. Предполагая, что у вас есть гигабайты памяти, узким местом, скорее всего, будет структура данных, которую вы используете для файловой системы. Если структура файловой системы громоздка, это замедлит вас.

Предполагая, что все остальные проблемы решены, вы беспокоитесь о самом приложении. Обратите внимание, что большинство узких мест находятся за пределами вашего программного контроля. Поэтому, независимо от того, кодируете ли вы его на C/C++ или используете определенные библиотеки, вы все равно будете зависеть от ОС и аппаратного обеспечения.

Если все машины работают под Windows в одной локальной сети, зачем вам вообще нужен сервер? Почему бы просто не использовать общий доступ к файлам Windows?

Я бы предложил не использовать FTP, или SFTP, или любую другую технику, ориентированную на соединение. Вместо этого используйте протокол или технику без установления соединения.

Причина в том, что, если вам требуется загрузить или загрузить много небольших файлов, а ответ должен быть максимально быстрым, вы хотите избежать затрат на установку и уничтожение соединений.

Я бы посоветовал вам рассмотреть либо использование существующей реализации, либо реализацию собственного HTTP / HTTPS-сервера / службы.

Похоже, вы должны использовать SFTP (SSH) сервер, он защищен брандмауэром /NAT, безопасен и уже делает то, что вы хотите, и даже больше. Вы также можете использовать SAMBA или общий доступ к файлам Windows для еще более простой реализации.

Почему бы не использовать что-то существующее, например, обычный веб-сервер очень хорошо и быстро обрабатывает множество небольших файлов (изображений).

И многие люди уже потратили время на оптимизацию кода.

И второе преимущество заключается в том, что передача осуществляется по HTTP, который является установленным протоколом. И легко переключается на SSL, если вам нужно больше безопасности.

Для загрузок у них также нет проблем со скриптом или пользовательским модулем - тем же способом вы также можете добавить авторизацию.

Пока вам не нужно динамически искать файлы, я думаю, это будет одним из лучших решений.

Это новая часть существующего настольного приложения? Какова цель сервера? Защищает ли он файлы, которые загружены / загружены, и обеспечивает аутентификацию и / или авторизацию? Предоставляет ли это какую-то структуру для загрузки, которая будет сохранена?

Один из вариантов может состоять в том, чтобы установить Apache HTTP Server на компьютере и передать файл через него. Используйте POST для загрузки и GET для загрузки.

Если клиенты находятся в локальной сети, не могли бы вы просто разделить диск?

Другие вопросы по тегам