#.net #sockets #tcp
#.net #сокеты #tcp
Вопрос:
При настройке System.Net.Sockets.TcpClient
объекта я начинаю использовать .Client.SetSocketOption()
функцию. Перечисления, найденные на сайте MSN, содержат список значений перечисления. Однако существует много совпадений, т. Е.:
Enum SocketOptionName
Debug = 1
IPOptions = 1
NoChecksum = 1
NoDelay = 1
AcceptConnection = 2
BsdUrgent = 2
Expedited = 2
HeaderIncluded = 2
End Enum
Похоже, что между этими настройками нет синонимичной связи или какой-либо корреляции между ними и SocketOptionLevel
перечислением, с помощью которого они вызываются.
Как что-либо работает, когда их нечем отличить?
Ответ №1:
Похоже, что между этими настройками нет синонимичной связи или какой-либо корреляции между ними и перечислением SocketOptionLevel, с которым они вызываются.
SocketOptionName
Значения обычно не связаны друг с другом, нет. Но они связаны со SocketOptionLevel
значениями. На самом деле это указано в SocketOptionLevel
документации:
SocketOptionLevel
Перечисление определяет уровни параметров сокета, которые могут быть переданы методамSocket.SetSocketOption
иSocket.GetSocketOption
.SocketOptionName
Перечисленные значения сгруппированы поSocketOptionLevel
.
SocketOptionLevel
и SocketOptionName
отражают level
и optname
параметры WinSock setsockopt()
API, где:
SocketOptionLevel.Socket
( level=SOL_SOCKET
) определяет:
SocketOptionName.Debug
(optname=SO_DEBUG
)SocketOptionName.AcceptConnection
(optname=SO_ACCEPTCONN
)- …
SocketOptionLevel.IP
( level=IPPROTO_IP
) определяет:
SocketOptionName.IPOptions
(optname=IP_OPTIONS
)SocketOptionName.HeaderIncluded
(optname=IP_HDRINCL
)- …
SocketOptionLevel.Udp
( level=IPPROTO_UDP
) определяет:
SocketOptionName.NoChecksum
(optname=UDP_NOCHECKSUM
)- …
SocketOptionLevel.Tcp
( level=IPPROTO_TCP
) определяет:
SocketOptionName.NoDelay
(optname=TCP_NODELAY
)SocketOptionName.BsdUrgent
(optname=TCP_EXPEDITED_1122
) 1SocketOptionName.Expedited
(optname=TCP_EXPEDITED_1122
) 1- …
1: as SocketOptionName.BsdUrgent
и SocketOptionName.Expedited
оба принадлежат SocketOptionLevel.Tcp
и оба определены как 2, это означает, что они фактически являются одним и тем же параметром сокета, только под разными именами. В WinSock на IPPROTO_TCP
уровне определены отдельные параметры сокета для TCP_BSDURGENT
(0x7000) и TCP_EXPEDITED_1122
(0x0002). Поскольку SocketOptionName.BsdUrgent
и SocketOptionName.Expedited
оба определены как 2, они оба представляют TCP_EXPEDITED_1122
. В SocketOptionName
документации даже говорится, что они оба реализуют RFC 1222 (опечатка, на самом деле это означает RFC 1122).
Как что-либо работает, когда их нечем отличить?
Они различаются на SocketOptionLevel
. Это комбинация SocketOptionLevel
и SocketOptionName
совместной работы, которая определяет заданный параметр сокета, который может быть запрошен / настроен. Каждый из них SocketOptionLevel
определяет 1 или более SocketOptionName
значений для себя. Таким образом, есть место для перекрытия SocketOptionName
значений для разных SocketOptionLevel
значений.
Комментарии:
1. Отличный ответ. Таким образом, фактически отправка любого из имен SocketOptionName, соответствующих правильному перечислению, будет иметь правильный эффект в отношении уровня SocketOptionLevel. Интересно, что они решили разбить это таким образом.
2. @JCollins как я уже сказал, перечисления просто отражают то, что делает базовый WinSock
setsockopt()
API, который сам по себе отражает BSD socket API, используемый на других платформах. Параметры сокета сгруппированы по уровням, и внутри каждого уровня есть несколько названий параметров. Проще и расширяемо иметь 1 универсальный API, чем иметь несколько API для каждого уровня.