【问题标题】:How to find out the data size of a received udp packet如何找出接收到的 udp 数据包的数据大小
【发布时间】:2015-06-18 19:08:08
【问题描述】:

我用php开发了一个小型udp服务器

<?php
$socket = stream_socket_server("udp://0.0.0.0:1201", $errno, $errstr, STREAM_SERVER_BIND);
if (!$socket) {
    die("$errstr ($errno)");
}

do {
    $pkt = stream_socket_recvfrom($socket, 1, 0, $peer);
    echo "$peer\n";
} while ($pkt !== false);

?>

我想打印每个接收到的数据包的数据大小以及源端口和目标端口。

我该怎么做?

【问题讨论】:

    标签: php sockets networking udp


    【解决方案1】:

    如果您使用为 UDP 创建的套接字,则接收函数的返回值是数据包的大小。我查找了一些示例代码,然后专门针对 php :

    do {
        $pkt = stream_socket_recvfrom($socket, 1, 0, $peer);
        echo "$peer\n";
        stream_socket_sendto($socket, date("D M j H:i:s Y\r\n"), 0, $peer);
    } while ($pkt !== false);
    

    正如我所料:接收函数 $pkt 的返回值是接收到的数据包的大小,而 $peer 是接收到的内容。

    如果您要打印 $pkt 的值,您会看到它包含数据包大小。

    UDP 上的数据包大小对应用程序很重要。如果您使用 UDP 并发送 2050 个字节,如果数据包没有丢失,您将在接收器处准确收到这 2050 个字节。所以在正常情况下没有必要甚至不可能访问UDP头。也不需要去原始套接字。 UDP可以发送的数据包大小基本上受到IP大小的限制。 (64k) 因为 IP 将在发送过程中对数据包进行分段,并在接收端进行碎片整理。碎片可以乱序接收等。 IP 只是将它们重新组合在一起。

    为避免混淆,我指的是用户作为有效载荷发送和接收到 UDP 的数据包的大小。

    参考string stream_socket_recvfrom ( resource $socket , int $length [, int $flags = 0 [, string &amp;$address ]] ) 来自http://php.net/manual/en/function.stream-socket-recvfrom.php

    表明您也可以获得发送给您的人的地址。

    【讨论】:

    • 如果消息$pkt被多个UDP数据包分段怎么办?
    • UDP 位于 IP 之上。 IP 处理碎片,您总是收到整个数据包。答案中提到了。如果用户需要大于 64K 的消息大小。然后,他必须在他的应用程序中在 UDP 之上自己设置一些东西。 TFTP 使用“更小的块来发送大文件”
    • 我的意思是远端可能只发送一个字节两次,当它是两个 udp 数据包时,你会一次收到两个字节。
    • 如果远程通过 UDP 发送单个字节两次,接收器也将收到 2 个单个字节。 UDP不是流式传输的TCP。 UDP 是基于数据包的。
    • 我的意思是在应用程序级别,您的代码在其中运行。您不能相信 socket_recv() 返回的是单个 UDP paket 的数据部分。您可以尝试以下示例:binarytides.com/udp-socket-programming-in-php ..(在服务器中添加两次 sock_sendto() 调用,看看它是如何搞砸的)
    【解决方案2】:

    您的代码在 udp 级别上不起作用,这意味着 udp 通信本身将由内核处理。您正在应用程序级别工作,您只是收到数据。如果数据分散在多个更新包中,则不会注意到这一点。这是 OSI 堆栈中的设计。

    如果您在 UDP 级别进行通信,您可以在 UDP 标头中获取每个包的大小。为此,您需要使用 原始套接字。但我认为这仅出于教育目的才有趣。

    通常应用程序代码不关心单个 UDP 数据包的大小,而是关心 消息 的大小。消息格式在上层应用协议中定义。例如,HTTP 定义了 Content-Length 标头。

    【讨论】:

      猜你喜欢
      • 2016-01-08
      • 2011-01-16
      • 2020-06-23
      • 1970-01-01
      • 2018-03-22
      • 1970-01-01
      • 2010-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多