SHOEISHA iD

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

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

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

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

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


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

マルチキャスト

 ブロードキャストは、複数の送信先を指定できるという役割は十分に果たしています。しかしながら、問答無用で送信しますので無駄も多い方式でした。その無駄をはぶくのがマルチキャストです。

 マルチキャストはクラスDのIPアドレスを使用します。クラスDのIPアドレスは他のクラス(A、B、C)とは違い、ネットワーク部とホスト部がありません。他のクラスと区別するために、先頭4ビットが1110となっており、それ以外の部分は「マルチキャスト・グループID」となっています。指定できる範囲は224.0.0.0から239.255.255.255です。

 マルチキャストでは送信先をホスト・グループと呼びます。ホスト・グループは複数のネットワークにもまたがえ、参加するホストは動的に変化させることができます。ここがブロードキャストとは違う点であり、参加していないホストはデータを受け取りません。なお、送信側は同じホスト・グループに所属している必要はありません。

 マルチキャスト・グループIDはIANA(Internet Assigned Numbers Authority)によっていくつか割り当てられており、マルチキャスト・グループIDには意味が付与されています。例えば、244.0.0.1は「このサブネット上のすべてのシステム」、224.0.1.1はNTP(Network Time Protocol)用などが存在します。

 今回は224.0.0.1の動きを簡潔に表現したMulticastTestサンプルを使用して説明します。

 MulticastTestサンプルを実行してください。このプロジェクトでは、端末Aが自分と同じサブネットを持つ端末へ向けてデータを送信しています。初め送信するときは、マルチキャストに参加しておらず、同じサブネットを持つ端末Bはデータを破棄します。次に、マルチキャストに端末Bが参加した状態でデータが送信されると端末Bはデータを受信します。

MulticastTestの実行画面
MulticastTestの実行画面
マルチキャストの動きを模倣したコード(C#)
//IPクラスより抜粋
/// <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.IsMulticast(packet.DestinationAddress) == true){
                this.m_udp.Multicast ( data );
                return;
            }
        }
    //関係のないコードは省略しています
}
マルチキャストの動きを模倣したコード(VB.NET)
'IPクラスより抜粋
''' <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.IsMulticast(packet.DestinationAddress) = True Then
                Me.m_udp.Multicast(data)
                Return
            End If
        End If
    '関係のないコードは省略
End Sub

'UDPクラスより抜粋
''' <summary>
''' マルチキャストを実行します。
''' </summary>
''' <param name="frame">送信するデータ</param>
Public Sub Multicast(ByVal frame As Frame)
    '処理に必要なデータを取得する
    If TypeOf frame Is MacFrame = False Then
        Return
    End If
    Dim packet As IPv4 = CType(frame.Data, IPv4)
    Dim address As MulticastAddress = CType(packet.DestinationAddress, MulticastAddress)

    'マルチキャストの値に基づいて適切な処理をする
    Select Case CType(address.HostAddress, MulticastAddressValue)
        Case MulticastAddressValue.AllSystemSubnet
            If TypeOf packet.SourceAddress Is SubNetAddress = True Then
                Dim target As SubNetAddress = CType(packet.SourceAddress, SubNetAddress)
                For Each cable As LanCable In Me.m_lan.ConnectCables
                    Dim com As SubNetAddress = CType(cable.ConnectNic.ConnectPc.Address, SubNetAddress)
                    If target.SubNet = com.SubNet AndAlso target <> com Then
                        cable.SendDataToNic(frame)
                    End If
                Next
            End If
        Case Else
            Throw New NotSupportedException( _
            address.HostAddress.ToString() & "はサポートされておりません。")
    End Select
End Sub

 実際のマルチキャストは、IGMP(Internet Group Management Protocol:インターネット・グループ・マネジメント・プロトコル)を使用する必要がありますが、イメージを掴みやすくするために省略しました。

 これでUDPに関連する事柄の解説は終わりです。次項ではTCPについて解説します。

TCPの概要

 UDPの項で少し触れましたが、TCPは信頼性の高い通信を行うためのプロトコルです。そのためUDPに比べてヘッダも複雑です。まずはヘッダの内容を説明します。

TCPヘッダフォーマット
TCPヘッダフォーマット

 各フィールドの内容は次のようになっています。

各フィールドの説明
フィールド 説明
発信元ポート番号(16ビット) 発信元が指定しているポート番号です。ポート番号とはアプリケーション層のプロトコルを特定するための番号です。ただし、ポート番号とプロトコルは一対一の関係ではなく、FTPのように複数のポート番号を使用するプロトコルも存在します。
宛て先ポート番号(16ビット) 宛て先に使用するプロトコル番号です。
シーケンス番号(32ビット) パケットへと分割された上位層のデータの位置を表す番号です。TCP/IPプロトコルスイーツではデータをパケットに分割するのでこのフィールドが必要なのです。
確認応答番号(32ビット) 送り手が予想している次のシーケンス番号です。ネットワークでは何らかのトラブルでデータが消失することがありますので、データが正常に届いているのか確認するためにこのフィールドを使用します。
ヘッダ長(4ビット) ヘッダの長さを表す値です。オプションフィールドが可変であり、長さが固定ではないのでこのフィールドが存在します。
予約済み(6ビット) 予約されている場所で、今の所内容は規定されていません。
6個のフラグ(6ビット) それぞれの名称は、URG・ACK・PSH・RST・SYN・FINです。同時にフラグを立てることができます。このフラグの使い方についてはその都度説明します。
ウインドウサイズ(16ビット) 一度に送ることのできるセグメント(TCPではデータの単位はセグメントです)です。詳しくは次回説明します。
チャックサム(16ビット) データが壊れていないかチェックするための値です。この連載では解説を省略しています。
緊急ポインタ(16ビット) URGフラグがONの時のみ有効なフィールドで、緊急を要するデータを指定する際に使用します。

 UDPに比べて複雑なのはヘッダだけではありません。その動作も少し複雑です。TCPではサービスを提供する側(サーバー)とサービスを要求する側(クライアント)が相互にやり取りをしながら通信をします。これにより、データ消失に対処できる信頼性の高い通信を実現できます。

 TCPではデータをやり取りする2台のホスト(通常はクライアントとサーバー)は、コネクションと呼ばれる仮想的な通信路を確立するところから処理を始めます。コネクションが確立された後は、2台のホストが互いに確認しながらデータを送受信し、最後は確立したコネクションを終了させます。

 アプリケーション層の解説をまだしておりませんのでデータの送信ができません。そこで、今回はコネクションの確立と終了を解説します。

 コネクションの確立と終了の動きを目で確認するためにTcpTestサンプルを実行してください。

TcpTestの実行画面
TcpTestの実行画面

 このサンプルプロジェクトでは、端末Aが同じLAN上にあるサーバーAと、他のLANにあるサーバーBとコネクションの確立と終了を行っています。動作の詳細についてはこれからサンプルコードを交えつつ解説します。

次のページ
コネクションの確立

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

  • 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」など、さまざまなカンファレンスを企画・運営しています。

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

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

メールバックナンバー

アクセスランキング

アクセスランキング