Help us understand the problem. What is going on with this article?

IPv4 によるブロードキャスト

More than 1 year has passed since last update.

1. 概要

この記事では、IPv4 によるブロードキャスト実現のための Golang サンプルコード投稿します。

2. はじめに

前回までの記事では、IPv4 や IPv6 によるマルチキャストの記事を投稿しました。

cast_type.png

今回の記事では、IPv4 によるブロードキャスト実現のための Golang サンプルコードにより、以下 2 パターンのアドレスを使用して動作の検証を行います。

  • ブロードキャストアドレス 1(192.0.2.255/24)
  • ネットワークアドレス2(192.0.2.0/24)

ブロードキャストは、マルチキャスト同様、UDP 通信となり、送信ノードの処理コスト削減にはとても有用ですが、特にブロードキャストの場合には、ネットワークコストや中継ノードのコスト増になるケースもありますので、適宜最適なキャストタイプの選択をした設計が必要でしょう。

3. 環境

  • RHEL-7 系
  • Go 1.9

4. 構成

  • node1
    • 192.0.2.1/24
  • node2
    • 192.0.2.2/24

5. Golang サンプルコード

@ node1, 2
$ sudo nvim ~/go/broadcast_ipv4.go

~/go/broadcast_ipv4.go
package main

import (
    "fmt"
    "net"
    "os"
    "time"
)

var InboundToAddr string = "" // 動作検証で切り替えます
var OutboundFromAddr string = "" // 動作検証で切り替えます
var OutboundToAddr string = "" // 動作検証で切り替えます
var BufferByte int = 64
var IntervalSeconds int = 1

func main() {

    // Start inbound
    go func() {
        inbound_to_addr_byte, err := net.ResolveUDPAddr("udp", InboundToAddr)
        Error(err)

        inbound, err := net.ListenUDP("udp", inbound_to_addr_byte)
        Error(err)
        defer inbound.Close()
        fmt.Printf("Listened *:* > %s\n", InboundToAddr)

        buffer := make([]byte, BufferByte)
        for {
            // Inbound message
            length, inbound_from_addr_byte, err := inbound.ReadFrom(buffer)
            Error(err)
            inbound_message := string(buffer[:length])

            inbound_from_addr := inbound_from_addr_byte.(*net.UDPAddr).String()

            fmt.Printf("Inbound %v > %v as “%s”\n", inbound_from_addr, InboundToAddr, inbound_message)
        }
    }()

    // Start outbound
    outbound_from_addr, err := net.ResolveUDPAddr("udp", OutboundFromAddr)
    outbound_to_addr, err := net.ResolveUDPAddr("udp", OutboundToAddr)
    outbound, err := net.DialUDP("udp", outbound_from_addr, outbound_to_addr)
    Error(err)
    defer outbound.Close()
    fmt.Printf("Connected %s > %s\n", OutboundFromAddr, OutboundToAddr)

    // Get hostname
    outbound_message, err := os.Hostname()
    Error(err)

    for {
        time.Sleep(time.Duration(IntervalSeconds) * time.Second)

        // Outbound message
        outbound.Write([]byte(outbound_message))
        fmt.Printf("Outbound %v > %v as “%s”\n", outbound_from_addr, outbound_to_addr, outbound_message)
    }

}

func Error(_err error) {
    if _err != nil {
        panic(_err)
    }
}

6. Golang サンプル実行

以下では、ブロードキャストアドレスへの送受信と、ネットワークアドレスへの送受信のパターンの動作検証をします。

6-1. ブロードキャストアドレス

ブロードキャストアドレスへの送受信の動作検証を実施します。

@ node1
送信: 192.0.2.1:56789 > 192.0.2.255:56789
受信: all > 192.0.2.255:56789
$ sudo nvim ~/go/broadcast_ipv4.go

~/go/broadcast_ipv4.go
var InboundToAddr string = "192.0.2.255:56789" // ブロードキャストアドレス
var OutboundFromAddr string = "192.0.2.1:56789"
var OutboundToAddr string = "192.0.2.255:56789" // ブロードキャストアドレス

@ node2
送信: 192.0.2.2:56789 > 192.0.2.255:56789
受信: all > 192.0.2.255:56789
$ sudo nvim ~/go/broadcast_ipv4.go

~/go/broadcast_ipv4.go
var InboundToAddr string = "192.0.2.255:56789" // ブロードキャストアドレス
var OutboundFromAddr string = "192.0.2.2:56789"
var OutboundToAddr string = "192.0.2.255:56789" // ブロードキャストアドレス

@ node1
受信成功

[user@node1 ~/go]$ sudo go run broadcast_ipv4.go
Connected 192.0.2.1:56789 > 192.0.2.255:56789
Listened *:* > 192.0.2.255:56789
Outbound 192.0.2.1:56789 > 192.0.2.255:56789 as “node1”
Inbound 192.0.2.1:56789 > 192.0.2.255:56789 as “node1”
Inbound 192.0.2.2:56789 > 192.0.2.255:56789 as “node2”
...

@ node2
受信成功

[user@node2 ~/go]$ sudo go run broadcast_ipv4.go
Connected 192.0.2.2:56789 > 192.0.2.255:56789
Listened *:* > 192.0.2.255:56789
Outbound 192.0.2.2:56789 > 192.0.2.255:56789 as “node2”
Inbound 192.0.2.1:56789 > 192.0.2.255:56789 as “node1”
Inbound 192.0.2.2:56789 > 192.0.2.255:56789 as “node2”
...

6-2. ネットワークアドレス

ネットワークアドレスへの送受信の動作検証を実施します。

@ node1
送信: 192.0.2.1:56789 > 192.0.2.0:56789
受信: all > 192.0.2.0:56789
$ sudo nvim ~/go/broadcast_ipv4.go

~/go/broadcast_ipv4.go
var InboundToAddr string = "192.0.2.0:56789" // ネットワークアドレス
var OutboundFromAddr string = "192.0.2.1:56789"
var OutboundToAddr string = "192.0.2.0:56789" // ネットワークアドレス

@ node2
送信: 192.0.2.2:56789 > 192.0.2.0:56789
受信: all > 192.0.2.0:56789
$ sudo nvim ~/go/broadcast_ipv4.go

~/go/broadcast_ipv4.go
var InboundToAddr string = "192.0.2.0:56789" // ネットワークアドレス
var OutboundFromAddr string = "192.0.2.2:56789"
var OutboundToAddr string = "192.0.2.0:56789" // ネットワークアドレス

@ node1
受信成功

[user@node1 ~/go]$ sudo go run broadcast_ipv4.go
Connected 192.0.2.1:56789 > 192.0.2.0:56789
Listened *:* > 192.0.2.0:56789
Outbound 192.0.2.1:56789 > 192.0.2.0:56789 as “node1”
Inbound 192.0.2.1:56789 > 192.0.2.0:56789 as “node1”
Inbound 192.0.2.2:56789 > 192.0.2.0:56789 as “node2”
...

@ node2
受信成功

[user@node2 ~/go]$ sudo go run broadcast_ipv4.go
Connected 192.0.2.2:56789 > 192.0.2.0:56789
Listened *:* > 192.0.2.255:56789
Outbound 192.0.2.2:56789 > 192.0.2.0:56789 as “node2”
Inbound 192.0.2.1:56789 > 192.0.2.0:56789 as “node1”
Inbound 192.0.2.2:56789 > 192.0.2.0:56789 as “node2”
...

7. まとめ

この記事では、IPv4 によるブロードキャスト実現のための Golang サンプルコード投稿しました。
このように、ブロードキャストアドレスやネットワークアドレスの利用により、サブネット内におけるブロードキャストが実現可能となります。
また、マルチキャストと同様、ブロードキャストも UDP 通信となり、送信ノードの処理コスト削減にはとても有用ですが、特にブロードキャストの場合には、ネットワークコストや中継ノードのコスト増になるケースもありますので、適宜最適なキャストタイプの選択をした設計が必要でしょう。

KyojiOsada
CAIO(Chief AI Officer)、CPO(Chief Product Officer)の他、社外 CTO、社外 VPoE、技術顧問など兼任、日本 CTO 協会、日本 CAIO 協会、全脳アーキテクチャイニシアティブ、日本ディープラーニング協会、人工知能学会、情報処理学会、電子情報通信学会、HRテクノロジーコンソーシアム、MyData Japan などに参加
https://kyowg.blogspot.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away