Из того, что я читал о NIO Java и не блокирующийся [Сервер] SocketChannels, должно быть возможно записать сервер TCP, который выдерживает несколько соединений с помощью только одного потока - я сделал бы Селектор, который ожидает всех соответствующих каналов в цикле сервера.
Это правильно, или я пропускаю некоторую важную деталь? С какими проблемами я могу встретиться?
(Фон: коммуникация TCP была бы для маленькой многопользовательской игры, таким образом, максимум 10-20 одновременных соединений. Сообщения будут отправлены о каждых нескольких секундах.)
Да, вы правы. Проблемы могут возникнуть, когда длительность обработки слишком велика. В этом случае вам придется обернуть обработку внутри другого потока, чтобы она не мешала сетевому потоку и предотвратила заметную задержку.
Еще одна деталь; каналы - это все о "перемещении" данных. Если ваши данные, которые вы хотите отправить, готовы, то вы можете переместить их в сетевой канал. Копирование/буферизация/и т.д. выполняется реализацией NIO.
Ваш однопоточный "сетевой поток" только управляет соединением, но не дросселирует его (читай: странная аналогия с автомобилем).
Базовый многопоточный подход проще в разработке и реализации, чем однопоточный NIO. Прирост производительности не заметен в небольшом многопользовательском игровом сервере/клиенте, особенно если сообщение отправляется только раз в несколько секунд.
Да, можно. См. этот пример для иллюстрации того, как это сделать.
Важный раздел:
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();
}
Все это хорошо работает, когда обработка на стороне сервера для каждого клиента незначительна. Однако многопоточный подход будет масштабироваться намного лучше.
Брайан Агнью сказал:
Все это работает хорошо, когда обработка на стороне сервера для каждого клиента незначительна. Однако многопоточный подход будет масштабироваться намного лучше.
Прошу не согласиться. Подход «один клиент - один поток» будет исчерпывать память намного быстрее, чем при обработке нескольких клиентов на поток, поскольку вам не понадобится полный стек для каждого клиента. См. Статью C10K для получения дополнительной информации по этой теме: http://www.kegel.com/c10k.html
В любом случае, если клиентов не будет больше 20, просто используйте то, что проще всего кодировать и отлаживать.