Порт по-прежнему используется после закрытия DatagramSocket - PullRequest
1 голос
/ 29 декабря 2011

Следующий код может воспроизвести проблему: int errAt = -1;

  try {
    System.out.println("start...");
    for (int i = 0; i < 4000; i++) {
      errAt = i;
      DatagramSocket result = new DatagramSocket(null);
      result.bind(new InetSocketAddress(InetAddress.getLocalHost(), 9005));
      result.close();
      //System.out.println(i);
    }

  } catch (Exception e) {
    System.out.println("Error: " + e.getMessage());
    System.out.println("ErrAt: " + errAt);
    e.printStackTrace();
  } finally {
    System.out.println("end...");
  }

На моем ПК я увижу исключение "java.net.BindException: Адрес уже используется: Не удается связать" послезапустить 2k + раз.

Я не уверен, означает ли это, что метод close не закрыл собственный сокет сразу?

Ответы [ 3 ]

2 голосов
/ 29 декабря 2011

Этот код работает на моем Mac, даже если я настроил его запускать 40000 итераций.Я думаю, что вероятная проблема здесь заключается в том, что сокет не закрывается сразу в Windows, но опять же вы пытаетесь выполнить тысячи итераций в течение, вероятно, миллисекунд.

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

    long tCumulative = 0;
    int errAt = -1;
    System.out.println("start...");
    for (int i = 0; i < 4000; i++) {
        try {
            errAt = i;
            DatagramSocket result = new DatagramSocket(null);
            result.bind(new InetSocketAddress(InetAddress.getLocalHost(), 9005));
            result.close();

            //success at last
            tCumulative = 0;

        } catch (Exception e) {
            System.out.println("Error (at="+errAt+") (waited="+tCumulative+"ms): " + e.getMessage());

            tCumulative+=50;
            Thread.sleep(50);
            i--;
        }
    }
    System.out.println("end...");
1 голос
/ 29 декабря 2011

Если вы создаете сокет, но затем получаете, например, BindException вы не закрываете сокет. Он должен быть закрыт в блоке finally {}.

Трудно увидеть смысл этого теста. Обычные программы UDP открывают one DatagramSocket и оставляют его открытым на весь процесс. Ни одна здравомыслящая программа не пролезла бы через тысячи сокетов UDP.

1 голос
/ 29 декабря 2011

Непонятно, что вы пытаетесь сделать, но один из способов обойти проблему, связанную с тем, что UDP-порт все еще используется, - установить параметр «адрес повторного использования» перед привязкой.

Ссылка: Как установить опцию повторного использования адреса для сокета дейтаграммы в коде Java?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...