Входящие соединения на нескольких сокетах

До сих пор мы говорили о разных видах входящих соединений применительно к одному сокету. На самом деле объект sock. поддерживает до 16 сокетов, и у каждого может быть своя настройка. То, что входящее соединение отклонено или проигнорировано на одном сокете, ещё не значит, что оно не будет установлено на другом!

Когда объект sock. получает сетевой пакет, он пытается найти сокет, для которого этот только что пришедший пакет приемлем.

Сначала объект sock. проверяет, можно ли считать пакет частью какого-либо существующего соединения или попыткой повторного подключения к существующему соединению. Проверяются все сокеты, занятые соединением в данный момент, начиная с сокета 0, затем 1, 2 и далее до sock.numofsock - 1.

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

Если выясняется, что ни один сокет, занятый соединением, не может принять пакет, объект sock. проверяет все простаивающие сокеты: сможет ли какой-нибудь из них принять этот пакет как новое входящее соединение. Снова проверяются все простаивающие сокеты, начиная с сокета 0 и далее до sock.numofsock - 1.

Для TCP пакет, способный начать такое новое соединение, - это специальный пакет «SYN». Для UDP новое соединение может начать любая входящая датаграмма, которую способен принять сокет (это зависит от его настройки).

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

Пример

Допустим, у нас такая настройка:

sock.num= 0
sock.protocol= PL_SOCK_PROTOCOL_TCP
sock.inconmode= PL_SOCK_INCONMODE_SPECIFIC_IP_ANY_PORT
sock.targetip="192.168.100.40"
sock.reconmode= PL_SOCK_RECONMODE_2
sock.localportlist= "1001"
sock.num=1
sock.protocol= PL_SOCK_PROTOCOL_TCP
sock.inconmode= PL_SOCK_INCONMODE_ANY_IPPORT
sock.localportlist= "1001"
sock.num=2
sock.protocol= PL_SOCK_PROTOCOL_UDP
sock.inconmode= PL_SOCK_INCONMODE_ANY_IPPORT
sock.localportlist= "2000"

Вот пример последовательности входящих соединений и того, как их обработает приведённая выше настройка:

Входящая датаграммаРеакция сокета
Входящее соединение TCP на порт 1001 от хоста 192.168.100.40:29600Соединение будет принято на сокете 0, поскольку этот сокет указывает 1001 среди портов прослушивания, а запрос входящего соединения пришёл от «правильного» хоста.
Входящее соединение TCP на порт 1001 от хоста 192.168.100.40:29601Оно будет воспринято как повторное подключение на сокете 0: это входящее соединение от того же хоста, что и предыдущее, и оно направлено на тот же порт 1001.
Входящее соединение TCP на порт 1001 от хоста 192.168.100.41:900Соединение будет принято на сокете 1, потому что сокет 0 уже занят соединением, а этот новый запрос нельзя истолковать как повторное подключение (другой хост).
Входящая датаграмма UDP на порт 2000 от хоста 192.168.100.40:320Эта датаграмма будет принята на сокете 2, и будет открыто «соединение».
Исходный материал Tibbo обновлён 10 августа 2022Оригинал на docs.tibbo.com · Сообщить об ошибке