Сокеты Java: я могу записать сервер TCP с одним потоком?

Из того, что я читал о NIO Java и не блокирующийся [Сервер] SocketChannels, должно быть возможно записать сервер TCP, который выдерживает несколько соединений с помощью только одного потока - я сделал бы Селектор, который ожидает всех соответствующих каналов в цикле сервера.

Это правильно, или я пропускаю некоторую важную деталь? С какими проблемами я могу встретиться?

(Фон: коммуникация TCP была бы для маленькой многопользовательской игры, таким образом, максимум 10-20 одновременных соединений. Сообщения будут отправлены о каждых нескольких секундах.)

5
задан hmp 14 March 2010 в 17:54
поделиться

3 ответа

Да, вы правы. Проблемы могут возникнуть, когда длительность обработки слишком велика. В этом случае вам придется обернуть обработку внутри другого потока, чтобы она не мешала сетевому потоку и предотвратила заметную задержку.

Еще одна деталь; каналы - это все о "перемещении" данных. Если ваши данные, которые вы хотите отправить, готовы, то вы можете переместить их в сетевой канал. Копирование/буферизация/и т.д. выполняется реализацией NIO.
Ваш однопоточный "сетевой поток" только управляет соединением, но не дросселирует его (читай: странная аналогия с автомобилем).

Базовый многопоточный подход проще в разработке и реализации, чем однопоточный NIO. Прирост производительности не заметен в небольшом многопользовательском игровом сервере/клиенте, особенно если сообщение отправляется только раз в несколько секунд.

2
ответ дан 15 December 2019 в 00:57
поделиться

Да, можно. См. этот пример для иллюстрации того, как это сделать.

Важный раздел:

for (;;) { // Loop forever, processing client connections
  // Wait for a client to connect
  SocketChannel client = server.accept();

  // Build response string, wrap, and encode to bytes (elided)

  client.write(response);
  client.close();
}

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

0
ответ дан 15 December 2019 в 00:57
поделиться

Брайан Агнью сказал:

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

Прошу не согласиться. Подход «один клиент - один поток» будет исчерпывать память намного быстрее, чем при обработке нескольких клиентов на поток, поскольку вам не понадобится полный стек для каждого клиента. См. Статью C10K для получения дополнительной информации по этой теме: http://www.kegel.com/c10k.html

В любом случае, если клиентов не будет больше 20, просто используйте то, что проще всего кодировать и отлаживать.

2
ответ дан 15 December 2019 в 00:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: