我开发了一个带有php
<?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);
?>
我想打印每个收到的数据包的数据大小以及源端口和目标端口。
我怎么能这样做?
答案 0 :(得分:1)
如果使用为UDP创建的套接字,则receive函数的返回值是数据包的大小。我查了一些示例代码,但后来专门针对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 &$address ]] )
来自http://php.net/manual/en/function.stream-socket-recvfrom.php
表示您也可以获取发送给您的人的地址。
答案 1 :(得分:0)
您的代码在udp级别上不起作用,这意味着udp通信本身将由内核处理。您正在处理应用程序级别,您只是收到数据。如果数据在多个更新的片段中被分段,则不会注意到这一点。这是OSI堆栈中的设计。
如果您在UDP级别进行通信,则可以在UDP标头中获取每个paket的大小。您需要使用原始套接字。但我认为这只会出于教育目的而有趣。
通常,应用程序代码不关心单个UDP pakets的大小,而是关心消息的大小。消息格式在上层应用程序协议中定义。例如,HTTP定义Content-Length
标头。