Согласно RFC 793, порт является 16-битным беззнаковым целым.
Это означает, что диапазон составляет 0 - 65535.
Однако в этом диапазоне порты 0–1023 обычно зарезервированы для определенных целей. Я говорю вообще, потому что, кроме порта 0, обычно нет применения резервирования 0-1023. Реализации TCP / UDP обычно не обеспечивают резервирование, кроме 0. Вы можете, если хотите, запустить порт TLS веб-сервера на порту 80, или 25, или 65535 вместо стандартного 443. Аналогично, даже если SMTP-серверы прослушивают порт 25 по стандарту, вы можете запустить его на 80, 443 или других.
Большинство реализаций резервируют 0 для конкретной цели - случайного назначения порта. Поэтому в большинстве реализаций выражение «прослушивать порт 0» фактически означает «мне все равно, какой порт я использую, просто дайте мне какой-нибудь случайный неназначенный порт для прослушивания».
Таким образом, любое ограничение на использование порта в диапазоне 0-65535, включая 0, диапазон временного резервирования и т. Д., Является специфичным для реализации (т. Е. ОС / драйвер) , однако все, включая 0, являются действительными портами. в RFC 793.
На протяжении многих лет я рассматривал проблему десятком разных способов, и единственное решение, которое я нашел, которое работает каждый раз, - это перестроить свое решение, чтобы не использовать циклическую ссылку .
Изменить:
Можете ли вы расширить? Например, как бы вы поступили с отношениями родитель-потомок, когда ребенку нужно знать о родителе / получить доступ к нему? - OB OB
Как я уже сказал, единственное хорошее решение - избегать таких конструкций если только вы не используете среду выполнения, которая может безопасно с ними справиться.
Тем не менее, если у вас должна быть структура данных дерево / родитель-потомок, в которой дочерний элемент знает о родителе, вам придется реализовать свою собственную, вручную вызываемую последовательность разборки (т.е. внешний по отношению к любым деструкторам, которые вы можете реализовать), который начинается в корне (или в ветви, которую вы хотите обрезать) и выполняет поиск в глубину дерева, чтобы удалить ссылки из листьев.
Это становится сложным и громоздким, поэтому ИМО единственное решение - полностью избежать этого.
Я знаю несколько способов обойти это:
Первый (и предпочтительный) - это просто извлечь общий код в третью сборку и заставить обе ссылки использовать этот
Второй добавляет ссылку как «Ссылка на файл» (dll) вместо «Ссылка на проект»
Надеюсь, это поможет
Я хотел бы предложить немного другой метод, который пришел ко мне, я не знаю, есть ли у него какое-либо официальное название:
Сами по себе объекты не имеют счетчика ссылок. Вместо этого группы из одного или нескольких объектов имеют один счетчик ссылок для всей группы, который определяет время жизни всех объектов в группе.
Аналогичным образом, ссылки разделяют группы с объектами или принадлежат к нулевой группе .
Ссылка на объект влияет на счетчик ссылок (object ' s) группа, только если она (ссылка) является внешней по отношению к группе.
Если два объекта образуют циклическую ссылку, они должны быть частью одной группы. Если две группы создают круговую ссылку, их следует объединить в одну группу.
Большие группы дают больше свободы ссылок, но объекты группы имеют больший потенциал остаться в живых, хотя в них нет необходимости.
Вот решение, которое я видел:
Добавьте метод к каждому объекту, чтобы сообщить ему, чтобы он освободил свои ссылки на другие объекты, скажем, назовите его Teardown ().
Затем вы должны знать, кто «владеет» каждым объектом, и владелец объекта должен вызвать для него Teardown (), когда он будет с ним работать.
Если существует циклическая ссылка, скажем, A <-> B, и C владеет A, то при вызове C's Teardown () он вызывает Teardown A, который вызывает Teardown на B, затем B освобождает свою ссылку на A, Затем A освобождает свою ссылку на B (уничтожая B), а затем C освобождает свою ссылку на A (уничтожает A).
I guess another method, used by garbage collectors, is "mark and sweep":