Перечисления SetSocketOption, предоставляемые платформой, имеют повторяющиеся записи. Как это работает?

#.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 ) 1
  • SocketOptionName.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 для каждого уровня.