Created
November 11, 2010 08:44
-
-
Save noqisofon/672211 to your computer and use it in GitHub Desktop.
ふにょふにょな UDP 送信窓クラス。
This file contains 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.Collections.Generic; | |
using System.ComponentModel; | |
using System.Data; | |
using System.Drawing; | |
using System.Net; | |
using System.Net.Sockets; | |
using System.Text; | |
using System.Threading; | |
using System.Windows.Forms; | |
namespace demo.udpclient.app.widgets { | |
using util; | |
/// <summary> | |
/// | |
/// </summary> | |
public partial class UDPClientForm : Form { | |
/// <summary> | |
/// | |
/// </summary> | |
public UDPClientForm() { | |
InitializeComponent(); | |
} | |
/// <summary> | |
/// ウィジェットの Text プロパティを設定するためのデリゲートです。 | |
/// </summary> | |
/// <param name="s"></param> | |
delegate void text_property_setter(string s); | |
/// <summary> | |
/// ウィジェットをメソッド内であれこれするためのデリゲートです。 | |
/// </summary> | |
delegate void action(); | |
/// <summary> | |
/// tbResult.Text に result を付け足します。 | |
/// </summary> | |
/// <remarks> | |
/// 呼び出し側が別スレッドで動いている場合、ウィジェット(コントロール)にアクセスすることはできないので、 | |
/// Invoke メソッドを使う。 | |
/// そのためのメソッド。 | |
/// </remarks> | |
/// <param name="result"></param> | |
private void result_append_to_textbox(string result) { | |
StringBuilder text_builder = new StringBuilder( tbResult.Text ); | |
text_builder.AppendLine( result ); | |
tbResult.Text = text_builder.ToString(); | |
} | |
/// <summary> | |
/// 「送信」ボタンを有効にします。 | |
/// </summary> | |
private void enable_send_button() { | |
if ( !btnSend.Enabled ) | |
btnSend.Enabled = true; | |
} | |
/// <summary> | |
/// 非同期受信に成功した場合に呼び出されます。 | |
/// </summary> | |
/// <param name="ar"></param> | |
private void async_receive_callback(IAsyncResult ar) { | |
UDPRecord record = (UDPRecord)ar.AsyncState; | |
if ( record.client.Client != null && record.client.Client.Connected ) { | |
byte[] received_bytes = record.client.EndReceive( ar, ref record.endpoint ); | |
record.client.Close(); | |
tbResult.Invoke( new text_property_setter( result_append_to_textbox ), | |
new object[] { Encoding.UTF8.GetString( received_bytes ) } | |
); | |
} | |
btnSend.Invoke( new action( enable_send_button ) ); | |
} | |
/// <summary> | |
/// 「送信」ボタンが押された場合に呼び出されます。 | |
/// </summary> | |
/// <param name="sender"></param> | |
/// <param name="ergs"></param> | |
private void btnSend_Click(object sender, EventArgs ergs) { | |
int src_port_numer = Convert.ToInt32( tbSrcPortNumber.Text ); | |
int dst_port_number = Convert.ToInt32( tbDstPortNumber.Text ); | |
this.udp_sender_ = new UdpClient( src_port_numer ); | |
this.udp_sender_.DontFragment = true; | |
this.udp_sender_.EnableBroadcast = true; | |
try { | |
// 送信先に接続します。 | |
this.udp_sender_.Connect( tbDstIpAddress.Text, dst_port_number ); | |
string send_text = string.Format( "<request><get version=\"{0}\">/</get><host>{1}</host></request>", | |
1.1, | |
tbDstIpAddress.Text | |
); | |
// 送信データを UTF-8 でエンコードしてバイト配列にします。 | |
byte[] send_bytes = Encoding.UTF8.GetBytes( send_text ); | |
int sended_bytes_amount = this.udp_sender_.Send( send_bytes, send_bytes.Length ); | |
Thread.Sleep( 1 ); | |
if ( sended_bytes_amount > 0 ) { | |
IPEndPoint remote_endpoint = new IPEndPoint( IPAddress.Any, 0 ); | |
//tbResult.Text = Encoding.UTF8.GetString( udp_sender.Receive( ref remote_endpoint ) ); | |
IAsyncResult ar = this.udp_sender_.BeginReceive( async_receive_callback, | |
new UDPRecord( this.udp_sender_, | |
remote_endpoint | |
) | |
); | |
btnSend.Enabled = false; | |
udpSenderTimer.Start(); | |
} else { | |
this.udp_sender_.Close(); | |
} | |
} catch ( SystemException se ) { | |
MessageBox.Show( se.ToString(), | |
se.Source, | |
MessageBoxButtons.OK, | |
MessageBoxIcon.Warning | |
); | |
this.udp_sender_.Close(); | |
} | |
} | |
/// <summary> | |
/// | |
/// </summary> | |
/// <param name="sender"></param> | |
/// <param name="ergs"></param> | |
private void udpSenderTimer_Tick(object sender, EventArgs ergs) { | |
if ( this.tick_ > 50 ) { | |
udpSenderTimer.Stop(); | |
this.udp_sender_.Close(); | |
MessageBox.Show( "応答がありませんでした。接続を閉じます。", | |
this.Text, | |
MessageBoxButtons.OK, | |
MessageBoxIcon.Information | |
); | |
return; | |
} | |
++this.tick_; | |
} | |
/// <summary> | |
/// UDP クライアント。 | |
/// </summary> | |
private UdpClient udp_sender_ = null; | |
/// <summary> | |
/// Timer#Tick イベントハンドラが呼び出された回数。 | |
/// </summary> | |
private int tick_ = 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment