LoginSignup
12
12

More than 5 years have passed since last update.

PHP でマルチキャストパケットを送信したり受信したり

Posted at

PHP 5.4 以上が必要。

送信側

<?php
$group = '239.255.1.1';
$port = 1234;
$iface = 'enp0s8';

$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_set_option($socket, IPPROTO_IP, IP_MULTICAST_IF, $iface);
socket_set_option($socket, IPPROTO_IP, IP_MULTICAST_LOOP, 0);

$data = implode(' ', array_slice($argv, 1));
socket_sendto($socket, $data, strlen($data), 0, $group, $port);
socket_close($socket);

受信側

<?php
$group = '239.255.1.1';
$port = 1234;
$iface = 'enp0s8';

$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($socket, '0.0.0.0', $port);
socket_set_option($socket, IPPROTO_IP, MCAST_JOIN_GROUP, [
    'group' => $group,
    'interface' => $iface,
]);

for (;;) {
    socket_recvfrom($socket, $buf, 1024, 0, $remoteAddr, $remotePort);
    echo "[$remoteAddr:$remotePort] $buf\n";
}

補足

  • 送信側は IP_MULTICAST_IF でインタフェースを指定して送信時にマルチキャストアドレス&ポートを指定する
  • 受信側は MCAST_JOIN_GROUP でインタフェースとマルチキャストアドレスを指定してマルチキャストグループに参加
  • IP_MULTICAST_IF を指定しない場合はルーティング結果の I/F から送信される
  • MCAST_JOIN_GROUP で I/F に 0 を指定するとルーティング結果の I/F が選択される
  • つまりデフォルトゲートウェイ側の I/F を使うなら IP_MULTICAST_IF は未指定で MCAST_JOIN_GROUP の I/F も 0 で良い
    • あるいは次のようなルーティングが設定されているか
    • ip route add 239.255.1.1/32 dev enp0s8
  • IP_MULTICAST_LOOP0 を指定すると同じホストでは受信されなくなる
    • 送信側と受信側を同じホストで実行しても受信しないという意味
    • デフォルトの 1 なら同じホストでも受信される
12
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12