SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

仮想ネットワークの実装で学ぶTCP/IP

仮想ネットワーク実装でTCP/IPを学ぼう(4)
― トランスポート層の勘所

仮想ネットワーク実装でTCP/IPを学ぼう(4)


  • X ポスト
  • このエントリーをはてなブックマークに追加

ブロードキャスト

 今までこの連載で取り扱ってきた、2台のホストで通信する形式をユニキャストと呼びます。その逆に、あるホストから複数のホストへデータを送りたい状況があります。それを実現する方式、すなわち複数台のホスト宛にデータを流す方式をブロードキャストと呼びます。前回ARPで要求フレームをLAN上に流しました。それをイメージすると分かりやすいと思います。

 主に使用されているブロードキャストは、リミテッド・ブロードキャスト、ネット・ダイレクト・ブロードキャスト、サブネット・ダイレクト・ブロードキャストの3種類あります。

ブロードキャストの名称について

 私が見た限り、ネットワークプロトコルを既定しているRFCには、ブロードキャストの名称が見当たりませんでした。そこで、『詳解TCP/IP Vol.1 プロトコル』(ピアソンエデュケーション刊)の第12章に記述されている名称を使用しています。

 まずは一番簡単なリミテッド・ブロードキャストを解説します。

 LimitedBroadcastTestサンプルを実行してみてください(サンプルファイルは記事添付のZIPファイルに同梱)。そうすると、端末Aから送られたデータが端末Aを含むすべての端末へ送られているのが確認できます。これからも分かるように、リミテッド・ブロードキャストとは、「LAN内のすべての端末が送信先」の方式であるデータ伝送方式です。

LimitedBroadcastTestの実行画面
LimitedBroadcastTestの実行画面

 リミテッド・ブロードキャストの動きをより深く知るためにサンプルプログラムを用いて解説をします。

リミテッド・ブロードキャストのアドレス形式(C#)
//IPv4クラスより抜粋
/// <summary>
/// リミテッド・ブロードキャストのアドレスを取得します。
/// </summary>
/// <returns>
/// リミテッド・ブロードキャストのアドレス
/// </returns>
public static ClassAddress GetLimitedBroadcastAddress ( )
{
    return new ClassAddress ( AddressClass.Special, uint.MaxValue );
}
リミテッド・ブロードキャストのアドレス形式(VB.NET)
'IPv4クラスより抜粋
''' <summary>
''' リミテッド・ブロードキャストのアドレスを取得します。
''' </summary>
''' <returns>
''' リミテッド・ブロードキャストのアドレス
''' </returns>
Public Shared Function GetLimitedBroadcastAddress() As ClassAddress
    Return New ClassAddress(AddressClass.Special, UInteger.MaxValue)
End Function

 リミテッド・ブロードキャストのアドレスは「255.255.255.255」です。サンプルプログラムでは、実装上の都合でSpecialとなっておりますが実際はクラスは定められていません。前回すべてのビットが1のアドレスはホストとし指定できないと書いたのはリミテッド・ブロードキャストのアドレスがすべてのビットが1だからです。リミテッド・ブロードキャストは、サブネットマスクやIPアドレスが分からない時に使用するものなのでこのように単純なアドレスとなっています。

 255.255.255.255のアドレスを受信したルーターは、自分が管理しているLAN内のすべてのホストにデータを送ることになっています。

リミテッド・ブロードキャスト受信時のルーターの動作の模倣(C#)
//Routerクラスより抜粋
/// <summary>
/// インターネット上へデータを送信します。
/// </summary>
/// <param name="data">送信するデータ</param>
public void Send ( Frame data )
{
    //準備
    if ( data.TypeOrLength == ( ushort ) EtherType.IP ) {
        IPv4 packet = ( IPv4 ) ( ( MacFrame ) data ).UsertData;
        //複数の宛て先が指定された時の処理
        if ( this.m_udp != null && packet.Protocol == Protocol.UDP) {
            //リミテッド・ブロードキャスト
            if ( IPv4.IsLimitedBroadcastAddress ( packet.DestinationAddress ) == true ) {
                this.m_udp.LimitedBroadcast ( data );
                return;
            }
    //他のコードは省略
}

//Udpクラスから抜粋
/// <summary>
/// リミテッド・ブロードキャストを実行します。
/// </summary>
/// <param name="frame">送信するデータ</param>
public void LimitedBroadcast ( Frame frame )
{
    IPv4 packet = (IPv4)frame.Data;
    UdpDatagram data = new UdpDatagram ( );
    packet.UserData = data;
    //LAN上のすべての端末にデータ送る
    foreach ( LanCable cable in this.m_lan.ConnectCables ) {
        cable.SendDataToNic ( frame );
    }
}
リミテッド・ブロードキャスト受信時のルーターの動作の模倣(VB.NET)
'Routerクラスから抜粋
''' <summary>
''' インターネット上へデータを送信します。
''' </summary>
''' <param name="data">送信するデータ</param>
Public Sub Send(ByVal data As Frame)
    '準備
    If data.TypeOrLength = CUShort(EtherType.IP) Then
        Dim packet As IPv4 = CType((CType(data, MacFrame)).UsertData, IPv4)
        '複数の宛て先が指定された時の処理
        If Not Me.m_udp Is Nothing Then
            'リミテッド・ブロードキャスト
            If IPv4.IsLimitedBroadcastAddress(packet.DestinationAddress) = True Then
                Me.m_udp.LimitedBroadcast(data)
                Retur
    '他のコードは省略
End Sub

'Udpクラスより抜粋
''' <summary>
''' リミテッド・ブロードキャストを実行します。
''' </summary>
''' <param name="frame">送信するデータ</param>
Public Sub LimitedBroadcast(ByVal frame As Frame)
    Dim packet As IPv4 = CType(frame.Data, IPv4)
    Dim data As UdpDatagram = New UdpDatagram()
    packet.UserData = data
    'LAN上のすべての端末にデータ送る
    For Each cable As LanCable In Me.m_lan.ConnectCables
        cable.SendDataToNic(frame)
    Next
End Sub

 以上の説明でリミテッド・ブロードキャストの説明は終わりです。次はネット・ダイレクト・ブロードキャストの説明をします。

 ネット・ダイレクト・ブロードキャストはネットワークだけを指定して、指定したネットワーク内のすべてのホストへブロードキャストをする方式の通信です。

 ネット・ダイレクト・ブロードキャストの動きを確認するために、NetDirectBroadcastTestサンプルを実行してみてください。このサンプルは、ホストEが他のネットワークに向けてネット・ダイレクト・ブロードキャストを送信する様子を表しています。実行すると端末A~Dが同時に受信しているのが確認できます。

NetDirectBroadcastTestの実行画面
NetDirectBroadcastTestの実行画面

 これからこの動作の詳細についてサンプルコードを用いて解説をします。

ネット・ダイレクト・ブロードキャストのアドレス形式(C#)
//IPv4クラスより抜粋
/// <summary>
/// ネット・ダイレクト・ブロードキャストのアドレスを取得します。
/// </summary>
/// <param name="addressClass">アドレスクラス</param>
/// <param name="netAddress">ネットワークアドレス</param>
/// <returns>
/// ネット・ダイレクト・ブロードキャストのアドレス
/// </returns>
public static ClassAddress GetNetDirectBroadcast (
    AddressClass addressClass,
    uint netAddress )
{
    ClassAddress result = new ClassAddress ( addressClass );
    result.NetworkAddress = netAddress;
    result.HostAddress = result.MaxHostAddress;
    return result;
}
ネット・ダイレクト・ブロードキャストのアドレス形式(VB.NET)
'IPv4クラスより抜粋
''' <summary>
''' ネット・ダイレクト・ブロードキャストのアドレスを取得します。
''' </summary>
''' <param name="addressClass">アドレスクラス</param>
''' <param name="netAddress">ネットワークアドレス</param>
''' <returns>
''' サブネット・ダイレクト・ブロードキャストのアドレス
''' </returns>
Public Shared Function GetNetDirectBroadcast( _
 ByVal addressClass As AddressClass, _
 ByVal netAddress As UInteger) As ClassAddress
    Dim result As ClassAddress = New ClassAddress(addressClass)
    result.NetworkAddress = netAddress
    result.HostAddress = result.MaxHostAddress
    Return result
End Function

 ネット・ダイレクト・ブロードキャストのアドレスは「ネット部が指定値」で「ホスト部がすべて1」です。例えば、クラスAのアドレスを持つネットワークを指定する場合X.255.255.255がネット・ダイレクト・ブロードキャストです。

 このアドレスを受信したルーターは、自分が管理するLAN内ならばすべてのホストへ送り、違うネットワークならばそこへデータを転送します。

ネット・ダイレクト・ブロードキャスト受信時のルーターの動作の模倣(C#)
//Routerクラスより抜粋
/// <summary>
/// インターネット上へデータを送信します。
/// </summary>
/// <param name="data">送信するデータ</param>
public void Send ( Frame data )
{
    //準備
    if ( data.TypeOrLength == ( ushort ) EtherType.IP ) {
        IPv4 packet = ( IPv4 ) ( ( MacFrame ) data ).UsertData;

        //複数の宛て先が指定された時の処理
        if ( this.m_udp != null && packet.Protocol == Protocol.UDP) {

            //サブネット・ダイレクト・ブロードキャスト
            if ( IPv4.IsSubNetDirectBroadcast ( packet.DestinationAddress, packet.SourceAddress ) == true ) {
                this.m_udp.SubNetDirectBroadcast ( data, this );
                return;
            }
    //関係のないコードは省略しています
}

//UDPクラスより抜粋
/// <summary>
/// ネット・ダイレクト・ブロードキャストを実行します。
/// </summary>
/// <param name="frame">送信するデータ</param>
/// <param name="router">送信元のルーター</param>
public void NetDirectBroadcast ( Frame frame, Router router )
{
    //処理に必要なデータを取得する
    IPv4 packet = ( IPv4 ) frame.Data;
    UdpDatagram data = new UdpDatagram ( );
    packet.UserData = data;

    //宛て先で指定されたネットアドレスを持つホストへデータを送信する
    foreach ( RoutingElement element in router.RoutingTable ) {
        if ( element.Destination.NetworkAddress == packet.DestinationAddress.NetworkAddress ) {
            router.Send ( element.Gateway, frame );
            return;
        }
    }

    //ここまで来たら自分が所属するLANが宛て先なのでブロードキャストする
    foreach ( LanCable cable in this.m_lan.ConnectCables ) {
        cable.SendDataToNic ( frame );
    }
}
ネット・ダイレクト・ブロードキャスト受信時のルーターの動作の模倣(VB.NET)
'Routerクラスより抜粋
''' <summary>
''' インターネット上へデータを送信します。
''' </summary>
''' <param name="data">送信するデータ</param>
Public Sub Send(ByVal data As Frame)
    '準備
    If data.TypeOrLength = CUShort(EtherType.IP) Then
        Dim packet As IPv4 = CType((CType(data, MacFrame)).UsertData, IPv4)

        '複数の宛て先が指定された時の処理
        If Not Me.m_udp Is Nothing Then

            'サブネット・ダイレクト・ブロードキャスト
            If IPv4.IsSubNetDirectBroadcast(packet.DestinationAddress, packet.SourceAddress) = True Then
                Me.m_udp.SubNetDirectBroadcast(data, Me)
                Return
            End If

    '関係のないコードは省略
End Sub

'UDPクラスより抜粋
''' <summary>
''' ネット・ダイレクト・ブロードキャストを実行します。
''' </summary>
''' <param name="frame">送信するデータ</param>
''' <param name="router">送信元のルーター</param>
Public Sub NetDirectBroadcast(ByVal frame As Frame, ByVal router As Router)

    '処理に必要なデータを取得する
    Dim packet As IPv4 = CType(frame.Data, IPv4)
    Dim data As UdpDatagram = New UdpDatagram()

    '宛て先で指定されたネットアドレスを持つホストへデータを送信する
    For Each element As RoutingElement In router.RoutingTable
        If element.Destination.NetworkAddress = packet.DestinationAddress.NetworkAddress Then
            router.Send(element.Gateway, frame)
            Return
        End If
    Next

    'ここまで来たら自分が所属するLANが宛て先なのでブロードキャストする
    For Each cable As LanCable In Me.m_lan.ConnectCables
        cable.SendDataToNic(frame)
    Next
End Sub

 最後にサブネット・ダイレクト・ブロードキャストの説明をします。サブネット・ブロードキャストは、指定したサブネットを持つ複数のホストへデータを送信する方式です。リミテッド・ブロードキャストよりも限定した範囲のホストへデータを送信したい時に使用します。これを確かめるために、SubNetDirectBroadcastTestサンプルを実行してください。そうすると、指定したサブネットを持つホストにしかデータが送信されていないことが確認できます。

SubNetDirectBroadcastTestの実行画面
SubNetDirectBroadcastTestの実行画面

 このサンプルは、端末Aがサブネット番号に4を指定して、自分が所属しているLANと他のネットワークに存在するLANにデータを送信する様子を表しています。実行すれば、サブネット番号が4のホストだけがデータを受信していることが確認できます。

 これからサブネット・ダイレクト・ブロードキャストについて、サンプルコードを交えて詳しく説明します。

サブネット・ダイレクト・ブロードキャストのアドレス形式(C#)
//IPv4クラスより抜粋
/// <summary>
/// サブネット・ダイレクト・ブロードキャストのアドレスを取得します。
/// </summary>
/// <param name="addressClass">アドレスクラス</param>
/// <param name="bitCount">サブネットのビット数</param>
/// <param name="netAddress">ネットワークアドレス</param>
/// <param name="subnet">サブネット部のアドレス</param>
/// <returns>
/// サブネット・ダイレクト・ブロードキャストのアドレス
/// </returns>
public static SubNetAddress GetSubNetDirectBroadcast (
    AddressClass addressClass,
    byte bitCount,
    uint netAddress,
    uint subnet)
{
    SubNetAddress result = new SubNetAddress (addressClass, bitCount);
    result.NetworkAddress = netAddress;
    result.SubNet = subnet;
    result.HostAddress = result.MaxHostAddress;
    return result;
}
サブネット・ダイレクト・ブロードキャストのアドレス形式(VB.NET)
'IPv4クラスより抜粋
''' <summary>
''' サブネット・ダイレクト・ブロードキャストのアドレスを取得します。
''' </summary>
''' <param name="addressClass">アドレスクラス</param>
''' <param name="bitCount">サブネットのビット数</param>
''' <param name="netAddress">ネットワークアドレス</param>
''' <param name="subnet">サブネット部のアドレス</param>
''' <returns>
''' サブネット・ダイレクト・ブロードキャストのアドレス
''' </returns>
Public Shared Function GetSubNetDirectBroadcast( _
 ByVal addressClass As AddressClass, _
 ByVal bitCount As Byte, _
 ByVal netAddress As UInteger, _
 ByVal subnet As UInteger) As SubNetAddress
    Dim result As SubNetAddress = New SubNetAddress(addressClass, bitCount)
    result.NetworkAddress = netAddress
    result.SubNet = subnet
    result.HostAddress = result.MaxHostAddress
    Return result
End Function

 サブネット・ダイレクト・ブロードキャストは、ネットワーク部とサブネット部を指定して、ホスト部をすべて1にしたアドレスを使用します。他のブロードキャストと違い、サブネット部が指定されているという点に注意してください。

 サブネット・ダイレクト・ブロードキャストの動作はネット・ダイレクト・ブロードキャストとほぼ同じです。違いは、「指定したサブネット部にだけデータを送る」点です。コードでこの動きを表現すると次のようになります。

サブネット・ダイレクト・ブロードキャスト受信時のルーターの動作の模倣(C#)
//Routerクラスより抜粋
/// <summary>
/// インターネット上へデータを送信します。
/// </summary>
/// <param name="data">送信するデータ</param>
public void Send ( Frame data )
{
    //準備
    if ( data.TypeOrLength == ( ushort ) EtherType.IP ) {
        IPv4 packet = ( IPv4 ) ( ( MacFrame ) data ).UsertData;

        //複数の宛て先が指定された時の処理
        if ( this.m_udp != null && packet.Protocol == Protocol.UDP) {
            //サブネット・ダイレクト・ブロードキャスト
            if ( IPv4.IsSubNetDirectBroadcast ( packet.DestinationAddress, packet.SourceAddress ) == true ) {
                this.m_udp.SubNetDirectBroadcast ( data, this );
                return;
            }
    //関係のないコードは省略しています
}

//UDPクラスより抜粋
/// <summary>
/// サブネット・ダイレクト・ブロードキャストを実行します。
/// </summary>
/// <param name="frame">送信するデータ</param>
/// <param name="router">実行するルーター</param>
public void SubNetDirectBroadcast ( Frame frame, Router router )
{
    //処理に必要なデータを取得する
    IPv4 packet = ( IPv4 ) frame.Data;
    UdpDatagram data = new UdpDatagram ( );
    packet.UserData = data;
    SubNetAddress target = packet.DestinationAddress as SubNetAddress;

    //宛て先で指定されたサブネットアドレスを持つホストへデータを送信する
    if ( router.SoftwareAddress.NetworkAddress == packet.DestinationAddress.NetworkAddress ) {
        //ルーターが属するLANへデータを送る
        if ( target != null ) {
            foreach ( LanCable cable in this.m_lan.ConnectCables ) {
                SubNetAddress address = cable.ConnectNic.ConnectPc.Address as SubNetAddress;
                if ( address != null && address.SubNet == target.SubNet ) //ここに注目してください
                    cable.SendDataToNic ( frame );
            }
        }
    } else {
        //他のLANへデータを送る
        router.SendToOtherLAN ( frame );
    }
}
サブネット・ダイレクト・ブロードキャスト受信時のルーターの動作の模倣(VB.NET)
'Routerクラスより抜粋
''' <summary>
''' インターネット上へデータを送信します。
''' </summary>
''' <param name="data">送信するデータ</param>
Public Sub Send(ByVal data As Frame)
    '準備
    If data.TypeOrLength = CUShort(EtherType.IP) Then
        Dim packet As IPv4 = CType((CType(data, MacFrame)).UsertData, IPv4)

        '複数の宛て先が指定された時の処理
        If Not Me.m_udp Is Nothing Then
            'サブネット・ダイレクト・ブロードキャスト
            If IPv4.IsSubNetDirectBroadcast(packet.DestinationAddress, packet.SourceAddress) = True Then
                Me.m_udp.SubNetDirectBroadcast(data, Me)
                Return
            End If
    '関係のないコードは省略
End Sub

'UDPクラスより抜粋
''' <summary>
''' サブネット・ダイレクト・ブロードキャストを実行します。
''' </summary>
''' <param name="frame">送信するデータ</param>
''' <param name="router">実行するルーター</param>
Public Sub SubNetDirectBroadcast(ByVal frame As Frame, ByVal router As Router)
    '処理に必要なデータを取得する
    Dim packet As IPv4 = CType(frame.Data, IPv4)
    Dim data As UdpDatagram = New UdpDatagram()
    packet.UserData = data
    If Not TypeOf packet.DestinationAddress Is SubNetAddress Then
        Return
    End If
    Dim target As SubNetAddress = CType(packet.DestinationAddress, SubNetAddress)

    '宛て先で指定されたサブネットアドレスを持つホストへデータを送信する
    If router.SoftwareAddress.NetworkAddress = packet.DestinationAddress.NetworkAddress Then
        'ルーターが属するLANへデータを送る
        For Each cable As LanCable In Me.m_lan.ConnectCables
            If TypeOf cable.ConnectNic.ConnectPc.Address Is SubNetAddress Then
                Dim address As SubNetAddress = CType(cable.ConnectNic.ConnectPc.Address, SubNetAddress)
                If address.SubNet = target.SubNet Then 'ここに注目してください
                    cable.SendDataToNic(frame)
                End If
            End If
        Next
    Else
        '他のLANへデータを送る
        router.SendToOtherLAN(frame)
    End If
End Sub

 以上でブロードキャストの説明は終わりです。

 次項ではブロードキャストに似た概念であるマルチキャストがありますのでそれを解説します。

次のページ
マルチキャスト

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
仮想ネットワークの実装で学ぶTCP/IP連載記事一覧

もっと読む

この記事の著者

インドリ(インドリ)

分析・設計・実装なんでもありのフリーエンジニア。ブログ「無差別に技術をついばむ鳥(http://indori.blog32.fc2.com/)」の作者です。アドバイザーをしたり、システム開発したり、情報処理技術を研究したりと色々しています。座右の銘は温故知新で、新旧関係なく必要だと考えたものは全て学...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4209 2010/04/27 12:07

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング