今回は、リスナー側のTCP通信アプリケーションの作成です。作成するダイアログは下記のようになります。あまり、クライアント側のTCP通信アプリケーションと違いはありませんね・・・。
ソースコードは以下の通りです。※クライアントからの接続待ち、接続、データの送受信の部分を抜粋です。
private void Btn_Start_Click(object sender, EventArgs e) { if (listener == null) { bStopFlg = false; clientList = new List(); //---------------------------------------------- // スレッド処理 //---------------------------------------------- ListenThread = new System.Threading.Thread(new System.Threading.ThreadStart(ListenStart)); ListenThread.IsBackground = true; ListenThread.Start(); } else { MessageBox.Show("接続待ちです。"); } } private void ListenStart() { //IPアドレスの設定、ポート番号の設定、TcpListener作成 System.Net.IPAddress ipAdd = System.Net.IPAddress.Parse(GettxBoxIP()); listener = new System.Net.Sockets.TcpListener(ipAdd, int.Parse(GettxBoxPort())); //Listenを開始する listener.Start(); SettxBoxReceive(GettxBoxReceive() + "Listenを開始しました(" + ((System.Net.IPEndPoint)listener.LocalEndpoint).Address + ":" + ((System.Net.IPEndPoint)listener.LocalEndpoint).Port + ")。¥r¥n"); SettxBoxReceiveScrollEnd(); //接続要求があったら受け入れる do { System.Net.Sockets.TcpClient client = null; try { client = listener.AcceptTcpClient(); } catch (SocketException e) { SettxBoxReceive(GettxBoxReceive() + "Listenerを閉じました。¥r¥n"); SettxBoxReceiveScrollEnd(); return; } SettxBoxReceive(GettxBoxReceive() + "クライアント(" + ((System.Net.IPEndPoint)listener.LocalEndpoint).Address + ")" + ((System.Net.IPEndPoint)listener.LocalEndpoint).Port + "と接続しました。¥r¥n"); SettxBoxReceiveScrollEnd(); clientList.Add(client); //---------------------------------------------- // スレッド処理 //---------------------------------------------- ReceiveThread = new System.Threading.Thread(ReceiveStart); ReceiveThread.IsBackground = true; ReceiveThread.Start(client); } while (bStopFlg == false); //リスナを閉じる listener.Stop(); listener = null; Console.WriteLine("Listenerを閉じました。"); SettxBoxReceive(GettxBoxReceive() + "Listenerを閉じました。¥r¥n"); SettxBoxReceiveScrollEnd(); } private void ReceiveStart(object iclient) { //クライアントから送られたデータを受信する System.Text.Encoding enc = System.Text.Encoding.UTF8; NetworkStream ns = null; TcpClient client = (TcpClient)iclient; //NetworkStreamを取得 ns = client.GetStream(); //タイムアウト設定 ns.ReadTimeout = 10000; ns.WriteTimeout = 10000; do { System.IO.MemoryStream ms = new System.IO.MemoryStream(); byte[] resBytes = new byte[256]; int resSize = 0; do { try { //データの一部を受信する resSize = ns.Read(resBytes, 0, resBytes.Length); } catch (IOException e) { } //受信したデータを蓄積する ms.Write(resBytes, 0, resSize); } while (ns.DataAvailable); //受信したデータを文字列に変換 string resMsg = enc.GetString(ms.GetBuffer(), 0, (int)ms.Length); ms.Close(); //末尾の¥nを削除 resMsg = resMsg.TrimEnd('¥n'); if (resMsg != "") { Console.WriteLine(resMsg); SettxBoxReceive(GettxBoxReceive() + resMsg + "¥r¥n"); SettxBoxReceiveScrollEnd(); } } while (bStopFlg == false); //閉じる ns.Close(); client.Close(); SettxBoxReceive(GettxBoxReceive() + "クライアントとの接続を閉じました。¥r¥n"); SettxBoxReceiveScrollEnd(); } private void Btn_Stop_Click(object sender, EventArgs e) { bStopFlg = true; } private void Btn_Send_Click(object sender, EventArgs e) { if (clientList.Count != 0) { //---------------------------------------------- // スレッド処理 //---------------------------------------------- SendThread = new System.Threading.Thread(new System.Threading.ThreadStart(SendStart)); SendThread.IsBackground = true; SendThread.Start(); } } private void SendStart() { //データを送信する System.Text.Encoding enc = System.Text.Encoding.UTF8; //Console.WriteLine(); foreach (TcpClient client in clientList) { NetworkStream ns = null; //NetworkStreamを取得 ns = client.GetStream(); //タイムアウト設定 ns.ReadTimeout = 10000; ns.WriteTimeout = 10000; //クライアントに送信する文字列を作成 string sendMsg = txtBox_Send.Text; //文字列をByte型配列に変換 byte[] sendBytes = enc.GetBytes(sendMsg + '¥r'); //データを送信する ns.Write(sendBytes, 0, sendBytes.Length); } }
リスナー側は、クライアント側の接続を待ちます。まずは、IPアドレスとポートを指定して、TcpListenerクラスをインスタンス化します。
listener = new System.Net.Sockets.TcpListener(ipAdd, int.Parse(GettxBoxPort()));
次に、TcpListenerのStartメソッドで接続待ちを開始します。
client = listener.AcceptTcpClient();
接続待ちをしている間、他の処理を受け付けなくなってしまうので、スレッド処理をしておいた方がよいです。クライアント側から接続があると、リスナーはクライアント情報を取得します。
client = listener.AcceptTcpClient();
このクライアント情報を使用して、データの送受信をします。データの送受信処理は、クライアント側の処理とほぼほぼ同じです。
クライアント側
サーバー側