Запись в сокет, который не был «принят» на ServerSocket? - PullRequest
2 голосов
/ 12 марта 2019

У меня есть простой сервер, который выглядит следующим образом

public static void main(String[] args) throws IOException {
    ServerSocket ss = new ServerSocket(4999);
    Socket s = ss.accept();
    InputStream is = s.getInputStream();
    while (true) {
        System.out.println(is.read());
    }
}

Он принимает один клиентский сокет, читает из него вечно и распечатывает номер, который был отправлен из клиентского сокета.

У меня есть такой клиент

public static void main(String[] args) throws IOException, InterruptedException {
    int id = Integer.valueOf(args[0]);
    Socket s = new Socket("localhost", 4999);
    OutputStream os = s.getOutputStream();
    while (true) {
        os.write(id);
        Thread.sleep(1000L);
        System.out.println("Sent");
    }
}

Он подключается к серверу и отправляет полученный номер в качестве аргумента командной строки навсегда.

  1. Я запускаю сервер.
  2. Я запускаю клиента, например java -jar client.jar 123.
  3. Затем запускаю другого клиента, например java -jar client.jar 234.
  4. Никаких ошибок не происходит ни на стороне сервера, ни на стороне клиента.
  5. Каждый клиент печатает сообщение Sent каждую 1 секунду, при этом ни один из них не блокируется.

Сервер печатает 123 только до конца времени.

Мои вопросы:

  1. Что происходит с байтами, записанными вторым клиентом?
  2. Я ожидаю, что второй клиент получит ошибку или будет заблокирован или что-то еще, но ничего не происходит.Почему?

Примечание: я знаю, что этот код плох, и я должен обрабатывать клиентов в потоках и вызывать ServerSocket.accept() и все такое прочее.

Обновление :

Исходя из принятого ответа, решение состоит в том, чтобы создать сервер наподобие new ServerSocket(4999, 1);, где 1 - размер отставания.0 будет означать использование любой настройки по умолчанию, настроенной в Java.

При использовании 1 в состоянии «не принято» может быть только одно соединение.Больше клиент, пытающийся подключиться, получает отказ в соединении!

1 Ответ

3 голосов
/ 12 марта 2019
  1. Байты, записанные вторым клиентом, попадут в буфер отправки клиента Socket, поскольку вы пишете в сокет, у которого еще нет установленного соединения.Со временем буфер отправки будет заполнен.Вы можете попробовать поиграть с Socket.setSendBufferSize(), чтобы посмотреть, что произойдет, когда он заполнится.
  2. A ServerSocket имеет список ожидания прослушивания для соединений, которые еще не были accept ed.Соединение со вторым клиентом находится в резерве, и если сервер когда-нибудь сможет обойти его (что не произойдет, с вашим кодом, но у клиента нет возможности узнать это), это будетустановлено, и клиентский буфер отправки будет весело отправлен.Вы можете попробовать вызвать конструктор ServerSocket(int port, int backlog) с резервом 1, чтобы посмотреть, что произойдет с клиентом, когда заполнится список ожидания прослушивания - он должен получить connection refused.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...