【问题标题】:C# UdpClient -- Ttl property vs. SetSocketOptionC# UdpClient -- Ttl 属性与 SetSocketOption
【发布时间】:2025-11-26 01:30:01
【问题描述】:

我在 C++ 中广泛使用了套接字编程,所以我了解所有套接字选项是什么等。现在我正在涉足 C#,并且遇到了一个我想解释的问题。

我在另一个开发人员启动的小应用程序中使用 UdpClient 类。我正在向多播地址发送数据包,因此我需要为数据包设置 TTL。我在这里查看文档:

http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.aspx

还有一个可以设置或获取的 TTL 属性。属性的帮助说“默认” ttl 是 128。如果我获取该属性,它是 128,在我设置属性并再次获取它之后,我可以验证该值已更改,但是,当我发送一个数据包,它的实际 TTL 设置为 1。

因为我比启动应用程序的人更了解网络,所以我尝试了这行代码(udpRecvClient 是 UdpClient 的名称):

updRecvClient.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 64);

这会导致我发送的数据包的正确 TTL 为 64,但读取 Ttl 属性仍会返回未更改的默认值 128。

那么什么给了?我是否误读了 Ttl 属性?我想知道问题出在哪里,以便在使用其他 C# 类时尽量避免它。现在,我只想对所有内容都使用 SetSocketOption 并忽略“有用的”属性。

注意updRecvClient.Client.Ttl也是一个属性,它也不会改变传出数据包的实际TTL。

【问题讨论】:

  • 您可能比我更了解网络,但是查看反射器中的程序集我发现设置 UdpClient.Ttl(与设置 UdpClient.Client.Ttl 相同)似乎最终会调用 SetSocketOption (SocketOptionLevel.IP,SocketOptionName.ReuseAddress,(int)值);现在我不知道这意味着什么,但对我来说它似乎与 TTL 没有任何关系?还是这样?
  • 傻我,看来 SocketOptionName.ReuseAddress 与 SocketOptionName.IpTimeToLive 相同(都是 4 值),所以我猜它与 TTL 有关。
  • 我想我不明白你在说什么。 ReuseAddress 是与 TTL 不同的设置,所以您是说在设置 TTL 属性时 MS 代码错误地调用了 ReuseAddress 吗?很抱歉回答的延迟。
  • 不,我错误地解释了代码,因为 ReuseAddress 和 IpTimeToLive 的底层值都是 4,这意味着无法区分它们。 SetSocketOption 方法通过查看指定的 SocketOptionLevel 来区分它们。如果使用 SocketOptionLevel.IP,则将其解释为 IpTimeToLive,如果使用 SocketOptionLevel.Socket,则将其解释为 ReuseAddress。很抱歉那里的混乱,我的错。据我所知,微软代码正在做正确的事情。

标签: c# udp multicast


【解决方案1】:

设置UdpClient.Ttl 属性等同于设置UdpClient.Client.Ttl。它最终调用:

 UdpClient.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, value)

(或 IPv6,取决于地址系列)。

所以我猜如果你想设置SocketOptionName.MulticastTimeToLive,你必须直接调用SetSocketOption,因为这与SocketOptionName.IpTimeToLive不同。

【讨论】:

  • 那么 TTL 属性是调用 ReuseAddress,还是调用这个 IpTimeToLive?我不知道有两个生存时间值,所以我不确定 IpTimeToLive 和 MulticastTimeToLive 之间有什么区别,除非 IPv6 有所不同。
  • ReuseAddress 的枚举值和 IpTimeToLive 相同,这意味着被调用的方法无法足够有趣地区分它们。不同的是,IpTimeToLive 选项是影响 SocketOptionLevel.IP 的选项,如果要设置 ReuseAddress 必须指定 SocketOptionLevel.Socket。
  • 有关 MulticastTimeToLive 和 IpTimeToLive 选项之间差异的一些信息,请参阅 social.msdn.microsoft.com/Forums/ar/netfxnetcom/thread/…