Created
December 14, 2010 07:02
-
-
Save noqisofon/740092 to your computer and use it in GitHub Desktop.
bit.ly/fuB06l のサンプルコードを読みやすくしてみた感じ。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using System.Net.Sockets; | |
using System.Text; | |
using System.IO; | |
using System.Threading; | |
namespace demo.multicasting.originator { | |
// The following ClientOriginator class starts the multicast conversation | |
// with the ClientTarget class.. | |
// It performs the following main tasks: | |
// 1)Creates a socket and binds it to the port on which to communicate. | |
// 2)Specifies that the connection must use an IPv6 address. | |
// 3)Joins or create a multicast group. | |
// Note that the multicast address ranges to use are specified | |
// in the RFC#2375. | |
// 4)Defines the endpoint to send the data to and starts the | |
// client target (ClientTarget) thread. | |
public class ClientOriginator { | |
/// <summary> | |
/// | |
/// </summary> | |
private UdpClient client_originator_; | |
/// <summary> | |
/// | |
/// </summary> | |
private IPAddress group_address_; | |
/// <summary> | |
/// | |
/// </summary> | |
private IPEndPoint client_target_dest_; | |
/// <summary> | |
/// | |
/// </summary> | |
private Thread worker_; | |
// The ConnectOriginatorAndTarget method connects the | |
// ClientOriginator with the ClientTarget. | |
// It performs the following main tasks: | |
// 1)Creates a UDP client to receive data on a specific port | |
// using IPv6 addresses. | |
// 2)Joins or create a multicast group at the specified address. | |
// 3)Defines the endpoint port to send data to on the ClientTarget. | |
// 4)Starts the ClientTarget thread that also creates the ClientTarget object. | |
// Note this method is the counterpart of the | |
// ClientTarget.StartMulticastConversation(). | |
public bool connectOriginatorAndTarget() { | |
try { | |
// Bind and listen on port 2000. This constructor creates a socket | |
// and binds it to the port on which to receive data. The family | |
// parameter specifies that this connection uses an IPv6 address. | |
this.client_originator_ = new UdpClient( 2000, AddressFamily.InterNetworkV6 ); | |
// Join or create a multicast group. The multicast address ranges | |
// to use are specified in RFC#2375. You are free to use | |
// different addresses. | |
// Transform the string address into the internal format. | |
this.group_address_ = IPAddress.Parse( "FF01::1" ); | |
// Display the multicast address used. | |
Console.WriteLine( "Multicast Address: [{0}]", this.group_address_ ); | |
// Exercise the use of the IPv6MulticastOption. | |
Console.WriteLine( "Instantiate IPv6MulticastOption(IPAddress)" ); | |
// Instantiate IPv6MulticastOption using one of the | |
// overloaded constructors. | |
IPv6MulticastOption ipv6_multicast_option = new IPv6MulticastOption( this.group_address_ ); | |
// Store the IPAdress multicast options. | |
IPAddress group = ipv6_multicast_option.Group; | |
long interface_index = ipv6_multicast_option.InterfaceIndex; | |
// Display IPv6MulticastOption properties. | |
Console.WriteLine( "IPv6MulticastOption.Group: [{0}]", group ); | |
Console.WriteLine( "IPv6MulticastOption.InterfaceIndex: [{0}]", interface_index ); | |
// Instantiate IPv6MulticastOption using another | |
// overloaded constructor. | |
IPv6MulticastOption ipv6_multicast_option2 = new IPv6MulticastOption( group, interface_index ); | |
// Store the IPAdress multicast options. | |
group = ipv6_multicast_option2.Group; | |
interface_index = ipv6_multicast_option2.InterfaceIndex; | |
// Display the IPv6MulticastOption2 properties. | |
Console.WriteLine( "IPv6MulticastOption.Group: [{0}]", group ); | |
Console.WriteLine( "IPv6MulticastOption.InterfaceIndex: [{0}]", interface_index ); | |
// Join the specified multicast group using one of the | |
// JoinMulticastGroup overloaded methods. | |
this.client_originator_.JoinMulticastGroup( (int)interface_index, group ); | |
// Define the endpoint data port. Note that this port number | |
// must match the ClientTarget UDP port number which is the | |
// port on which the ClientTarget is receiving data. | |
this.client_target_dest_ = new IPEndPoint( this.group_address_, 1000 ); | |
ClientTarget target = new ClientTarget( this.client_target_dest_ ); | |
// Start the ClientTarget thread so it is ready to receive. | |
this.worker_ = new Thread( new ThreadStart( target.startMulticastConversation ) ); | |
this.worker_.Start(); | |
// Make sure that the thread has started. | |
Thread.Sleep( 2000 ); | |
return true; | |
} catch ( Exception e ) { | |
Console.WriteLine( "[ClientOriginator.ConnectClients] Exception: {0}", e ); | |
return false; | |
} | |
} | |
// The SendAndReceive performs the data exchange | |
// between the ClientOriginator and the ClientTarget classes. | |
public string sendAndReceive() { | |
string ret = string.Empty; | |
Receiver receiver = new Receiver( this.client_originator_ ); | |
Sender sender = new Sender(this.client_originator_); | |
// Send data to ClientTarget. | |
Console.WriteLine( "\nThe ClientOriginator sent:\n" ); | |
sender.originatorSendData( this.client_target_dest_ ); | |
// Receive data from ClientTarget | |
ret = receiver.receiveUntilStop(); | |
// Stop the ClientTarget thread | |
worker_.Abort(); | |
// Abandon the multicast group. | |
client_originator_.DropMulticastGroup( this.group_address_ ); | |
return ret; | |
} | |
/// <summary> | |
/// This is the console application entry point. | |
/// </summary> | |
public static void Main() { | |
ClientOriginator originator = new ClientOriginator(); | |
// Join the multicast group. | |
if ( originator.connectOriginatorAndTarget() ) { | |
// Perform a multicast conversation with the ClientTarget. | |
string ret = originator.sendAndReceive(); | |
Console.WriteLine( "\nThe ClientOriginator received: \n\n{0}", ret ); | |
} else { | |
Console.WriteLine( "Unable to Join the multicast group" ); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using System.Net.Sockets; | |
using System.Text; | |
using System.IO; | |
using System.Threading; | |
namespace demo.multicasting.originator { | |
// The ClientTarget class is the receiver of the ClientOriginator | |
// messages. The StartMulticastConversation method contains the | |
// logic for exchanging data between the ClientTarget and its | |
// counterpart ClientOriginator in a multicast operation. | |
public class ClientTarget { | |
/// <summary> | |
/// | |
/// </summary> | |
private UdpClient client_; | |
/// <summary> | |
/// | |
/// </summary> | |
private IPAddress group_address_; | |
/// <summary> | |
/// | |
/// </summary> | |
public ClientTarget(IPEndPoint endpoint) { | |
// Bind and listen on port 1000. Specify the IPv6 address family type. | |
this.client_ = new UdpClient( endpoint.Port, AddressFamily.InterNetworkV6 ); | |
// Join or create a multicast group | |
this.group_address_ = endpoint.Address; | |
} | |
// The following StartMulticastConversation method connects the UDP | |
// ClientTarget with the ClientOriginator. | |
// It performs the following main tasks: | |
// 1)Creates a UDP client to receive data on a specific port and using | |
// IPv6 addresses. The port is the same one used by the ClientOriginator | |
// to define its communication endpoint. | |
// 2)Joins or creates a multicast group at the specified address. | |
// 3)Defines the endpoint port to send data to the ClientOriginator. | |
// 4)Receives data from the ClientOriginator until the end of the | |
// communication. | |
// 5)Sends data to the ClientOriginator. | |
// Note this method is the counterpart of the | |
// ClientOriginator.ConnectOriginatorAndTarget(). | |
public void startMulticastConversation() { | |
string ret; | |
// Use the overloaded JoinMulticastGroup method. | |
// Refer to the ClientOriginator method to see how to use the other | |
// methods. | |
this.client_.JoinMulticastGroup( this.group_address_ ); | |
// Define the endpoint data port. Note that this port number | |
// must match the ClientOriginator UDP port number which is the | |
// port on which the ClientOriginator is receiving data. | |
IPEndPoint client_originator_dest = new IPEndPoint( this.group_address_, 2000 ); | |
// Receive data from the ClientOriginator. | |
Receiver receiver = new Receiver( this.client_ ); | |
ret = receiver.receiveUntilStop(); | |
Console.WriteLine( "\nThe ClientTarget received: \n\n{0}\n", ret ); | |
// Done receiving, now respond to the ClientOriginator. | |
// Wait to make sure the ClientOriginator is ready to receive. | |
Thread.Sleep( 2000 ); | |
Console.WriteLine( "\nThe ClientTarget sent:\n" ); | |
Sender sender = new Sender( this.client_ ); | |
sender.targetSendData( client_originator_dest ); | |
// Exit the multicast conversation. | |
client_.DropMulticastGroup( this.group_address_ ); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using System.Net.Sockets; | |
using System.Text; | |
using System.IO; | |
using System.Threading; | |
namespace demo.multicasting.originator { | |
/// <summary> | |
/// The following Receive class is used by both the ClientOriginator and | |
/// the ClientTarget class to receive data from one another.. | |
/// </summary> | |
public class Receiver { | |
/// <summary> | |
/// | |
/// </summary> | |
public Receiver(UdpClient client) { | |
this.client_ = client; | |
this.session_teminator_ = "Over"; | |
} | |
/// <summary> | |
/// </summary> | |
/// <remarks> | |
/// The following static method performs the actual data | |
/// exchange. In particular, it performs the following tasks: | |
/// 1)Establishes a communication endpoint. | |
/// 2)Receive data through this end point on behalf of the | |
/// caller. | |
/// 3) Returns the received data in ASCII format. | |
/// </remarks> | |
/// <param name="client"></param> | |
/// <returns></returns> | |
public string receiveUntilStop() { | |
StringBuilder text_data_builder = new StringBuilder(); | |
string segment = string.Empty; | |
ASCIIEncoding ascii = new ASCIIEncoding(); | |
// Establish the communication endpoint. | |
IPEndPoint endpoint = new IPEndPoint( IPAddress.IPv6Any, 50 ); | |
while ( !segment.Equals( this.session_teminator_ ) ) { | |
byte[] data = this.client_.Receive( ref endpoint ); | |
segment = ascii.GetString( data ); | |
text_data_builder.AppendLine( segment ); | |
} | |
return text_data_builder.ToString(); | |
} | |
/// <summary> | |
/// | |
/// </summary> | |
private UdpClient client_; | |
/// <summary> | |
/// | |
/// </summary> | |
private string session_teminator_; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using System.Net.Sockets; | |
using System.Text; | |
using System.IO; | |
using System.Threading; | |
namespace demo.multicasting.originator { | |
/// <summary> | |
/// The following Send class is used by both the ClientOriginator and | |
/// ClientTarget classes to send data to one another. | |
/// </summary> | |
public class Sender { | |
/// <summary> | |
/// | |
/// </summary> | |
/// <param name="client"></param> | |
public Sender(UdpClient client) { | |
this.client_ = client; | |
} | |
/// <summary> | |
/// The following static method sends data to the ClientTarget on | |
/// behalf of the ClientOriginator. | |
/// </summary> | |
/// <param name="client"></param> | |
/// <param name="endpoint"></param> | |
public void originatorSendData(IPEndPoint endpoint) { | |
Console.WriteLine( new string( GREETINGS ) ); | |
this.client_.Send( getByteArray( GREETINGS ), GREETINGS.Length, endpoint ); | |
Thread.Sleep( 1000 ); | |
Console.WriteLine( new string( NICE ) ); | |
this.client_.Send( getByteArray( NICE ), NICE.Length, endpoint ); | |
Thread.Sleep( 1000 ); | |
Console.WriteLine( new string( EOM ) ); | |
this.client_.Send( getByteArray( EOM ), EOM.Length, endpoint ); | |
} | |
/// <summary> | |
/// The following static method sends data to the ClientOriginator on | |
/// behalf of the ClientTarget. | |
/// </summary> | |
/// <param name="client"></param> | |
/// <param name="endpoint"></param> | |
public void targetSendData(IPEndPoint endpoint) { | |
Console.WriteLine( new string( ORIGINATOR_GREETINGS ) ); | |
this.client_.Send( getByteArray( ORIGINATOR_GREETINGS ), ORIGINATOR_GREETINGS.Length, endpoint ); | |
Thread.Sleep( 1000 ); | |
Console.WriteLine( new string( TOO_NICE ) ); | |
this.client_.Send( getByteArray( TOO_NICE ), TOO_NICE.Length, endpoint ); | |
Thread.Sleep( 1000 ); | |
Console.WriteLine( new string( EOM ) ); | |
this.client_.Send( getByteArray( EOM ), EOM.Length, endpoint ); | |
} | |
// | |
/// <summary> | |
/// Internal utility | |
/// </summary> | |
/// <param name="cs"></param> | |
/// <returns></returns> | |
private static byte[] getByteArray(char[] cs) { | |
byte[] ret = new byte[cs.Length]; | |
for ( int i = 0; i < cs.Length; i++ ) | |
ret[i] = (byte)cs[i]; | |
return ret; | |
} | |
/// <summary> | |
/// | |
/// </summary> | |
private UdpClient client_; | |
/// <summary> | |
/// | |
/// </summary> | |
private static char[] GREETINGS = { 'H', 'e', 'l', 'l', 'o', ' ', | |
'T', 'a', 'r', 'g', 'e', 't', '.' }; | |
/// <summary> | |
/// | |
/// </summary> | |
private static char[] NICE = { 'H', 'a', 'v', 'e', ' ', 'a', ' ', 'n', 'i', | |
'c', 'e', ' ', 'd', 'a', 'y', '.' }; | |
/// <summary> | |
/// | |
/// </summary> | |
private static char[] EOM = { 'O', 'v', 'e', 'r' }; | |
/// <summary> | |
/// | |
/// </summary> | |
private static char[] ORIGINATOR_GREETINGS = { 'H', 'e', 'l', 'l', 'o', ' ', | |
'O', 'r', 'i', 'g', 'i', 'n', 'a', 't', 'o', 'r', '!' }; | |
/// <summary> | |
/// | |
/// </summary> | |
private static char[] TOO_NICE = { 'Y', 'o', 'u', ' ', 't', 'o', 'o', '.' }; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment