【问题标题】:UDP socket. How to determine if data is sent to wire?UDP 套接字。如何确定数据是否发送到线路?
【发布时间】:2012-05-25 20:32:45
【问题描述】:

我正在使用 UDP 套接字。服务器应用程序向客户端发送有关客户端应将数据传输到服务器多长时间的信息。然后,客户端在这段时间内通过发送特定的数据包开始传输。

所以我需要一种方法来确定数据是否在 Sendto() 之后发送到线路,以了解客户端实际发送了多少时间。存在吗?

操作系统:Windows 7

我尝试使用性能计数器(网络接口\输出队列长度)但它始终为0;

我知道的另一种方法是将 SO_SNDBUF ( setsockopt() ) 设置为要发送的数据包的大小。所以 sendto() 阻塞,直到发送套接字缓冲区已满(前一个数据包未发送到网络接口缓冲区)。但似乎它不起作用,只是因为它只适用于套接字缓冲区而不是网络接口缓冲区。

我也对 Linux 的解决方案感兴趣。

【问题讨论】:

  • UDP 不可靠(按设计)。我不确定您到底要做什么,但这是您无法解决的问题。如果您需要知道某物是否收到了消息,请使用 TCP 或其他一些可靠的协议。
  • 感谢您的评论。我不需要知道某事是否收到了消息。问题是什么时候发送它。我的意思是发送到线路,而不是放入套接字缓冲区或网络接口缓冲区。我只需要知道客户端发送数据的时间。
  • 该信息没有什么价值,因为您甚至无法保证是否会发送,如果是,则绝对不能保证会收到数据包。
  • “这些信息没有什么价值,因为你甚至不能保证是否会被发送”。 UDP 不保证发送?
  • 没有。成功的sendto 告诉您操作系统将您的数据包放入缓冲区。就这样。如果它与该内存有更好的关系,操作系统可以在此之后立即丢弃它。

标签: c++ sockets udp


【解决方案1】:

阅读上面 Mat 的评论。 通常使用 UDP,您必须假设数据在您调用 send() 方法后立即发送。无法确定数据是否实际发送和/或接收。

编辑:我的意思是没有办法确定数据已到达预期目的地。您可以检查数据是否正在发送,甚至可以在一定程度上跟踪它的路线。但是无法确保数据已收到,即使您的预期接收者可以访问,但这并不意味着他们正在收听......

【讨论】:

  • 事实上,你可以在MAC上设置RGMII/XGMII环回,例如,匹配数据包。或者你可以镜像传出端口并设置一个环回,这会有点贵,但是......肯定会告诉你:)至于这个解决方案的实用性 - 没有多大意义。
【解决方案2】:

我需要一种方法来确定数据是否在 Sendto() 之后发送到线路,以了解客户端实际发送了多少时间。存在吗?

至于sendto()是否成功将数据包发送到客户端,这可能比你需要做的工作更多。

为确保客户端仅在特定时间段内发送,您需要在服务器的数据包中包含剩余的传输时间。客户端还应该估计通过网络到达服务器所需的时间。使用这两个数字来估计客户端传输的剩余时间。

【讨论】:

  • 这无济于事,因为客户端必须知道它可以发送多少时间。例如,它发送了两个数据包(特定格式),它必须知道它是否可以发送更多? (时隙(传输时间)是否已过)
  • 您在问题中没有提及时间段。请修改您的问题,完整描述您的协议在服务器端和客户端的作用
  • 对不起。 “服务器应用程序向客户端发送有关客户端应将数据传输到服务器多长时间的信息”。我的意思是这次的“时间段”。也许我使用了错误的术语。
【解决方案3】:

我遇到了类似的问题,即使 send() 没有返回错误,UDP send() 也从未真正连接到网络上。

原来问题是 ARP 从来没有从本地链路主机得到响应,所以数据包在内部被丢弃了。

简单的答案是;如果您可以 PING 目标地址,您的 UDP 数据包几乎肯定会进入网络。如果 PING 显示“主机无法访问”,则不会。如果您只是用 tcpdump 或 wireshark 嗅探 UDP 数据包,您可能会认为您的设备有问题,因为,您的 UDP 数据包从未发送过!

因此还可以嗅探 ARP 响应,或者您甚至可以通过编程方式检查您的 ARP 缓存,以获取目标地址(如果是本地)或网关(如果不是)的条目。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多