框架提供的 SetSocketOption 枚举具有重复的条目。这是如何运作的?

The SetSocketOption enumerations provided by the Framework have duplicate entries. How does this work?

在设置 System.Net.Sockets.TcpClient 对象时,我开始使用 .Client.SetSocketOption() 函数。在 the MSN site 上找到的枚举列出了枚举值。但是有很多重叠,即:

Enum SocketOptionName
  Debug = 1
  IPOptions = 1
  NoChecksum = 1
  NoDelay = 1
  AcceptConnection = 2
  BsdUrgent = 2
  Expedited = 2
  HeaderIncluded = 2
End Enum

这些设置之间似乎没有同义关系,或者它们与调用它们的 SocketOptionLevel 枚举之间没有任何关联。

当没有什么可以区分它们时,它们如何工作?

There doesn't seem to be a synonymous relationship between these settings, or any correlation between them and the SocketOptionLevel enumeration they are called with.

SocketOptionName值一般彼此没有关系,没有。但它们与 SocketOptionLevel 值有关。这实际上在 SocketOptionLevel 文档中有说明:

The SocketOptionLevel enumeration defines the socket option levels that can be passed to the Socket.SetSocketOption and Socket.GetSocketOption methods. SocketOptionName enumerated values are grouped by SocketOptionLevel.

SocketOptionLevelSocketOptionName 镜像 WinSock setsockopt() API 的 leveloptname 参数,其中:

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:因为SocketOptionName.BsdUrgentSocketOptionName.Expedited都属于SocketOptionLevel.Tcp并且都定义为2,这意味着它们实际上是同一个套接字选项不同的名字。在 WinSock 中,IPPROTO_TCP 级别为 TCP_BSDURGENT (0x7000) 和 TCP_EXPEDITED_1122 (0x0002) 定义了单独的套接字选项。由于SocketOptionName.BsdUrgentSocketOptionName.Expedited都定义为2,所以它们都代表TCP_EXPEDITED_1122SocketOptionName 文档甚至说它们都实现了 RFC 1222(打字错误,它实际上意味着 RFC 1122)。

How does anything work when there is nothing to differentiate them?

它们的区别在于SocketOptionLevelSocketOptionLevelSocketOptionName 组合 共同定义了一个给定的套接字选项,可以是 queried/configured。每个 SocketOptionLevel 为自己定义 1 个或多个 SocketOptionName 值。因此,对于不同的 SocketOptionLevel 值,存在重叠 SocketOptionName 值的空间。