C# で TCP ってみた
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;
他のは窓魔術を扱ったり扱わなかったりでいれてる。
System.Threading 名前空間は要らないかも。
ということで、次。
/// <summary> /// /// </summary> /// <param name="text"></param> private void set_text_setter(string text) { StringBuilder resulttext_builder = new StringBuilder( tbResult.Text ); resulttext_builder.AppendLine( text ); tbResult.Text = resulttext_builder.ToString(); }
結果をテキストボックスに書き込みそうな関数。
+ でくっつけるのはかっこ悪いよね〜
で、次。
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="ergs"></param> private void btnSend_Click(object sender, EventArgs ergs) { TcpClient client = new TcpClient( AddressFamily.InterNetwork ); NetworkStream stream = null; set_text_setter( "送信ボタンが押されました。" );
とりあえず、TcpClient オブジェクトを作成するよ!!
IPAddress ip_address; if ( tbDstIpAddress.Text == String.Empty ) { IPHostEntry host = Dns.GetHostEntry( Dns.GetHostName() ); Stack<IPAddress> address_stack = new Stack<IPAddress>( host.AddressList ); // 0 番は IPv6 なので、IPv4 の IP アドレスにする。 ip_address = address_stack.Pop(); } else ip_address = IPAddress.Parse( tbDstIpAddress.Text ); int port = Convert.ToInt32( tbDstPort.Text ); IPEndPoint endpoint = new IPEndPoint( ip_address, port ); client.Connect( endpoint );
tbDstIpAddress はテキストボックスで、送信先の IP アドレスをいれとくやつだよ。
これが、空文字の時はローカルの IP アドレスを取得するよ!!
AddressList は IPAddress の配列なんだけど、私がやったときは IPv4 と IPv6 の 2 つが入ってて、
まー、めんどくさいのでスタックに入れて、pop することにした。
これは、IPv4 のアドレスが末尾に入ってるからなんだけどね。
それ以外なら、テキストボックスの中身を IP アドレスにパースするよっ!
無事に IP アドレスを取得できたら、ポート番号を数値に変換したりして connect するんだ。
よーし、次。
stream = client.GetStream(); if ( stream.CanWrite ) { string send_text = string.Format( "<request><get version=\"{0}\">/</get><host>{1}</host></request>", 1.1, tbDstIpAddress.Text ); byte[] send_bytes = Encoding.UTF8.GetBytes( send_text ); stream.Write( send_bytes, 0, send_bytes.Length ); }
UDP だと、普通に書き込んだり読み込んだりするんだけど、TCP の場合は NetworkStream オブジェクトから読んだり書き込んだりするんだ。
もしかしたら…ということで、CanWrite で書き込めるかどうか調べてから書き込む。
if ( stream.CanRead ) { client.ReceiveBufferSize = 256; byte[] received_bytes = new byte[client.ReceiveBufferSize]; int received_bytes_amount; string received_text = string.Empty; received_bytes_amount = stream.Read( received_bytes, 0, received_bytes.Length ); received_text = Encoding.UTF8.GetString( received_bytes, 0, received_bytes_amount ); set_text_setter( received_text ); }
送信したので、今度は受信する。
受信した文字列をテキストボックスに吐き出して終了。
if ( stream.CanRead ) { client.ReceiveBufferSize = 256; byte[] received_bytes = new byte[client.ReceiveBufferSize]; int received_bytes_amount; string received_text = string.Empty; received_bytes_amount = stream.Read( received_bytes, 0, received_bytes.Length ); received_text = Encoding.UTF8.GetString( received_bytes, 0, received_bytes_amount ); set_text_setter( received_text ); }
*1:じゃないけど