マルチキャスト
ブロードキャストは、複数の送信先を指定できるという役割は十分に果たしています。しかしながら、問答無用で送信しますので無駄も多い方式でした。その無駄をはぶくのがマルチキャストです。
マルチキャストはクラス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はデータを受信します。
//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; } } //関係のないコードは省略しています }
'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に比べてヘッダも複雑です。まずはヘッダの内容を説明します。
各フィールドの内容は次のようになっています。
フィールド | 説明 |
発信元ポート番号(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サンプルを実行してください。
このサンプルプロジェクトでは、端末Aが同じLAN上にあるサーバーAと、他のLANにあるサーバーBとコネクションの確立と終了を行っています。動作の詳細についてはこれからサンプルコードを交えつつ解説します。