Сокеты Java: могу ли я написать TCP-сервер с одним потоком? - PullRequest
5 голосов
/ 14 марта 2010

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

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

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

Ответы [ 3 ]

2 голосов
/ 15 марта 2010

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

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

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

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

2 голосов
/ 14 марта 2010

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

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

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

0 голосов
/ 14 марта 2010

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

Важный раздел таков:

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();
}

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

...