Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ふにょふにょな UDP 送信窓クラス。
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
You can’t perform that action at this time.