Отдельные потоки для ввода и вывода в Java TCP Server - PullRequest
0 голосов
/ 26 марта 2011

Мне было поручено написать tcp-сервер и клиент на Java.У меня возникли некоторые проблемы при разработке общей структуры моего сервера.Сервер должен принимать несколько соединений, но протокол ответа на запрос отсутствует.После установления соединения клиент может отправлять данные на сервер, а сервер может отправлять данные клиенту.Учитывая это, я решил, что для каждого соединения было бы неплохо иметь отдельные потоки ввода и вывода.Я просмотрел множество примеров, но большинство из них довольно простые и не имеют отдельных потоков для ввода и вывода.Я был бы очень признателен за любую помощь или совет.

Пока мой tcp-сервер имеет поток прослушивания, который прослушивает клиентские соединения.После установления соединения я создаю входной поток и выходной поток для этого подключения.

В TCPServer

while (true)
{
    SocketChannel clientChannel = m_serverChannel.accept();         
    new Thread(new ReadWorker(clientChannel)).start();
    new Thread(new WriteWorker(clientChannel)).start();
}

Как передать данные для отправки в выходные потоки?Сначала я хотел, чтобы выходные потоки прослушивали очередь ожидающих данных, отправляя данные по мере их доступности.

В TCPServer

ConcurrentHashMap<SocketChannel, LinkedBlockingQueue<ByteBuffer>> pendingWrites 
        = new ConcurrentHashMap<SocketChannel, LinkedBlockingQueue<ByteBuffer>>(); 

void broadcast(ByteBuffer buffer) {
    synchronized(pendingWrites) {

    Iterator it = pendingWrites.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry pairs = (Map.Entry)it.next();
        ((LinkedBlockingQueue<ByteBuffer>) pairs.getValue()).put(buffer);
    }
}

В WriteWorker

pendingWrites.get(socketChannel).take()
// send the data

Является ли это разумным решением?

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

Спасибо

1 Ответ

1 голос
/ 26 марта 2011

Вы не используете отдельные потоки ввода и вывода. У вас есть сокет, вы можете читать и писать в него.

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

Если вам нужно, чтобы сервер выводил что-то без получения ввода от клиента, вы бы заблокировали чтение с таймаутом или используете Selector (похоже, вы используете nio)

Я привел пример в ответе на SO, который может вам помочь: Проверка отключения клиента на сервере TCP TCP - только вывод

Это не использует новые классы NIO, но показывает, как вы будете использовать блокировку чтения с тайм-аутом.

...