Подтвердить что ты не робот

Некоторые вопросы о пакете Java

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

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

Ответ 2

A DatagramSocket остается связанным при отключении, это метод close(), который отменит его. Обратите внимание, что для сокета UDP (датаграммы) семантика connect() и disconnect() отличается от сокета TCP (или другого ориентированного на соединение). UDP - это протокол без установления соединения, а связанный DatagramSocket может отправлять и принимать пакеты без "подключения". Метод connect() имеет чисто локальный эффект, поскольку он заставляет сокет иметь возможность отправлять и принимать пакеты только на конкретный хост/порт, то есть действовать как фильтр. A 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);