Как работают повторные подключения UDP и переключение портов
Для «соединений» UDP повторные подключения тоже существуют. Из-за совершенно иной природы UDP (по сравнению с TCP) повторные подключения для UDP нужно объяснять отдельно. Кроме того, нам нужно ввести понятие «переключение портов» (port switchover).
Что такое переключение портов
В TCP каждая сторона соединения использует один порт и для отправки, и для приёма данных. В UDP это необязательно. Объект sock. в соединении может принимать данные с одного порта, а отправлять на другой!
Когда переключение портов отключено, сокет всегда адресует исходящие датаграммы UDP на порт, заданный свойством sock.targetport. Когда переключение портов включено, сокет адресует исходящие датаграммы на порт, с которого получена самая последняя входящая датаграмма!
Обратите внимание: о переключении IP-адреса мы ничего не говорили - пока речь шла только о портах.
Повторные подключения UDP
Как и для TCP, свойство sock.reconmode определяет для UDP, какая входящая датаграмма UDP заставит сокет забыть прежнее «соединение» и переключиться на новое. Есть два варианта: принимать повторные подключения только с определённого IP-адреса, но с любого порта, либо принимать с любого IP-адреса и любого порта. Сочетая это с двумя вариантами переключения портов, получаем четыре комбинации - четыре варианта для свойства sock.reconmode. Лучше всего это понять на примерах.
Пример: PL_SOCK_RECONMODE_0
Настройка:
sock.protocol= PL_SOCK_PROTOCOL_UDP 'we are dealing with UDP
sock.inconmode= PL_SOCK_INCONMODE_ANY_IPPORT
sock.reconmode= PL_SOCK_RECONMODE_0 'reconnects accepted from the same IP, any port, port switchover off
sock.localportlist= "3000"
sock.targetport= "900"
Датаграммы нам отправляют два хоста, и вот как отреагирует сокет:
| Входящая датаграмма | Реакция сокета |
| 192.168.100.40:1000 отправляет датаграмму UDP на порт 3000 нашего устройства | Датаграмма принята, «соединение» UDP установлено, все дальнейшие исходящие датаграммы сокет будет отправлять на 192.168.100.40:900. |
| 192.168.100.44:1001 отправляет датаграмму UDP на порт 3000 нашего устройства | Датаграмма проигнорирована - она пришла с другого IP-адреса. Сокет по-прежнему будет отправлять исходящие датаграммы на 192.168.100.40:900. |
| 192.168.100.40:1100 отправляет датаграмму UDP на порт 3000 нашего устройства | Повторное подключение принято (значит, датаграмма принята), но все дальнейшие исходящие датаграммы сокет по-прежнему будет отправлять на 192.168.100.40:900 (потому что переключение портов отключено). |
Пример: PL_SOCK_RECONMODE_1
Настройка:
sock.protocol= PL_SOCK_PROTOCOL_UDP 'we are dealing with UDP
sock.inconmode= PL_SOCK_INCONMODE_ANY_IPPORT
sock.reconmode= PL_SOCK_RECONMODE_1 'reconnects accepted from any IP/port, port switchover off
sock.localportlist= "3000"
sock.targetport= "900"
Датаграммы нам отправляют два хоста, и вот как отреагирует сокет:
| Входящая датаграмма | Реакция сокета |
| 192.168.100.40:1000 отправляет датаграмму UDP на порт 3000 нашего устройства | Датаграмма принята, «соединение» UDP установлено, все дальнейшие исходящие датаграммы сокет будет отправлять на 192.168.100.40:900. |
| 192.168.100.44:1001 отправляет датаграмму UDP на порт 3000 нашего устройства | Повторное подключение принято, все дальнейшие исходящие датаграммы сокет будет отправлять на 192.168.100.44:900. |
Пример: PL_SOCK_RECONMODE_2
Настройка:
sock.protocol= PL_SOCK_PROTOCOL_UDP 'we are dealing with UDP
sock.inconmode= PL_SOCK_INCONMODE_ANY_IPPORT
sock.reconmode= PL_SOCK_RECONMODE_2 'reconnects accepted from the same IP, any port, port switchover on
sock.localportlist= "3000"
sock.targetport= "900"
Датаграммы нам отправляют два хоста, и вот как отреагирует сокет:
| Входящая датаграмма | Реакция сокета |
| 192.168.100.40:1000 отправляет датаграмму UDP на порт 3000 нашего устройства | Датаграмма принята, «соединение» UDP установлено, все дальнейшие исходящие датаграммы сокет будет отправлять на 192.168.100.40:1000. |
| 192.168.100.44:1001 отправляет датаграмму UDP на порт 3000 нашего устройства | Датаграмма проигнорирована - она пришла с другого IP-адреса. Сокет по-прежнему будет отправлять исходящие датаграммы на 192.168.100.40:1000. |
| 192.168.100.40:1100 отправляет датаграмму UDP на порт 3000 нашего устройства | Повторное подключение принято, все дальнейшие исходящие датаграммы сокет будет отправлять на 192.168.100.40:1100. |
Пример: PL_SOCK_RECONMODE_3
Настройка:
sock.protocol= PL_SOCK_PROTOCOL_UDP 'we are dealing with UDP
sock.inconmode= PL_SOCK_INCONMODE_ANY_IPPORT
sock.reconmode= PL_SOCK_RECONMODE_3 'reconnects accepted from any IP/port, port switchover on
sock.localportlist= "3000"
sock.targetport= "900"
Теперь датаграммы нам отправляют два хоста, и вот как отреагирует сокет:
| Входящая датаграмма | Реакция сокета |
| 192.168.100.40:1000 отправляет датаграмму UDP на порт 3000 нашего устройства | Датаграмма принята, «соединение» UDP установлено, все дальнейшие исходящие датаграммы сокет будет отправлять на 192.168.100.40:1000. |
| 192.168.100.44:1001 отправляет датаграмму UDP на порт 3000 нашего устройства | Повторное подключение принято, все дальнейшие исходящие датаграммы сокет будет отправлять на 192.168.100.44:1001. |