Некоторые вопросы Java Datagram Socket - PullRequest
12 голосов
/ 15 июня 2011

Недавно я погрузился в программирование сокетов с использованием Java, и у меня есть несколько общих вопросов.

Существует метод bind (), а также connect () и disconnect (). Там нет unbind (). Это потому, что при отключении сокета нет связи? Собирается ли сбор мусора после выхода из программы? Или это даже не правильный вопрос?

Кроме того, после создания DatagramSocket, чем он отличается, если я указываю только порт и адрес? Я создаю программу для сбора данных из сети, так как данные перемещаются и регистрируют их. Должен ли я просто использовать локальный адрес? Не может ли использование адреса при создании сокета привести к невозможности сбора пакетов?

Я просто пытаюсь получить более глубокое понимание внутренней работы этих вещей.

Ответы [ 2 ]

16 голосов
/ 15 июня 2011

Там есть около 15 независимых вопросов, но я постараюсь ответить на них:

Существует метод bind (), а также connect () и disconnect ().Там нет unbind ().Это связано с тем, что при отключении сокета нет связи?

bind() отделен от connect() и disconnect().Bind используется для привязки сокета к определенному порту - фактически для «прослушивания» соединений, тогда как connect() используется для открытия соединения с сокетом, который уже прослушивает определенный порт.Эквивалент unbind() равен close()

Собирается ли сборщик мусора после выхода из программы?Или это даже не правильный вопрос?

Это полностью правильный вопрос, хотя сборка мусора - это технология, используемая для управления памятью, а не для управления ресурсами сокетов / ОС.Если вы не освободите определенный порт, он останется связанным с вашим приложением до тех пор, пока ваше приложение не прекратит работу, а затем будет возвращен ОС.Это функциональность на уровне ОС, а не функциональность JVM и т. Д.

Кроме того, чем отличается создание DatagramSocket, если я только предоставляю порт или указываю порт и адрес?

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

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

Я не уверен, что вы спрашиваете здесь, вы говорите о регистрации всех пакетов насеть, ака снифер?Это потребует больше, чем простое программирование дейтаграмм.На самом деле вам нужно ввести себя на уровне сетевого адаптера, чтобы перехватывать пакеты, когда они считываются с линии.То, о чем вы говорите, позволит вам только получать пакеты, отправленные на определенный порт, который вы слушаете.

12 голосов
/ 15 июня 2011

A DatagramSocket остается связанным, когда отсоединен, это - метод close(), который бы связал его.Обратите внимание, что для сокета UDP (дейтаграммы) семантика connect() и disconnect() отличается от сокета TCP (или другого ориентированного на соединение).UDP - это протокол без установления соединения, и связанный DatagramSocket может отправлять и получать пакеты, не будучи «подключенным».Метод connect() имеет чисто локальный эффект в том смысле, что он позволяет сокету только отправлять и получать пакеты на заданный хост / порт, т.е. действовать как фильтр.DatagramSocket, подключенный к многоадресному или широковещательному адресу, сможет только отправлять пакеты и не получать их.

bind(SocketAddress) используется для подключения сокета к комбинации локального адреса / порта до того, как сокет будетсвязан он не может получать или отправлять какие-либо пакеты.Поведение конструкторов по умолчанию заключается в немедленном связывании сокета.Чтобы создать несвязанный DatagramSocket, используйте конструктор DatagramSocket(SocketAddress), передав в качестве аргумента null.Затем можно применить любую пользовательскую конфигурацию к сокету, прежде чем связать его с bind().

Насколько мне известно, открытое DatagramSocket, выходящее за пределы области действия, вызовет утечку ресурсов, объект можетбыть сборщиком мусора, но я уверен, что базовый сокет UDP будет выделяться ОС до тех пор, пока не завершится процесс JVM.

Если адрес не указан до того, как сокет будет привязан, при привязке он будет подключен кподстановочный адрес (INADDR_ANY), что позволяет ему принимать и отправлять пакеты с любого доступного локального адреса (если только он позднее не «подключен» к какому-либо хосту).Если порт не указан (или указан как 0), то сокет привязывается к некоторому доступному порту, выбранному ОС ( эфемерный порт ).

Редактировать: пример

// bind to INADDR_ANY, allowing packets on all IP addresses of host:
DatagramSocket dsock = new DatagramSocket(55555);
DatagramPacket packet = new DatagramPacket(new byte[8192]);

//next packet can be from anywhere including local host (127.0.0.0/8)
dsock.receive(packet);

// restrict communication to a single host/port:
dsock.connect(new InetSocketAddress("somehost.net", 99));

// next packet can only be from somehost.net on port 99:
dsock.receive(packet);
...