【やさしいC#】lesson10.5 スレッド

C#

スレッドの仕組みを知る

  さて、ネットワークを介したプログラムでは、相手先からのデータの受信を待機し続けながら処理をすることがあります。しかし、このようにネットワーク上の相手先のやりとりに時間がかかると、プログラムがそれ以外の処理をすることができなくなってしまいます。
  そこで、ネットワークを扱うプログラムでは、スレッド(thread)と呼ばれる機能を利用するのが一般的です。1つのスレッドで相手を待機する処理をしながら、もう1つのスレッドで、別の処理をするのです。

スレッド
ネットワークプログラミングでは、スレッドを起動して待機処理を行うことがあります。

スレッドによるプログラムを作成する

  そこで私たちも早速、スレッドを使ってネットワークプログラムを作成してみることにしましょう。次のコードを見てください。

//sample6S.cs
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace lesoon10
{
    class sample6S
    {
        public static string HOST = "localhost";
        public static int PORT = 10000;
        static void Main(string[] args)
        {
            IPHostEntry ih = Dns.GetHostEntry(HOST);
            TcpListener tl = new TcpListener(ih.AddressList[0], PORT);
            tl.Start();

            Console.WriteLine("待機します。");
            while (true)
            {
                TcpClient tc = tl.AcceptTcpClient();
                Console.WriteLine("よこそう。");

                Client c = new Client(tc);
                Thread th = new Thread(c.run);
                th.Start();  //クライアントとやり取りするスレッドを起動します
            }
        }
    }

    class Client
    {
        TcpClient tc;
        public Client(TcpClient c)
        {
            tc = c;
        }
        public void run()  //クライアントとやり取りするスレッドの処理
        {
            StreamWriter sw = new StreamWriter(tc.GetStream());
            StreamReader sr = new StreamReader(tc.GetStream());

            //クライアントから文字列を読み込み、新しい文字列をつけて送り続ける処理です
            while (true)
            {
                try
                {
                    string str = sr.ReadLine();
                    sw.WriteLine("サーバー:「" + str + "」ですね。");
                    sw.Flush();
                }
                catch
                {
                    sr.Close();
                    sw.Close();
                    tc.Close();
                }
            }
        }
    }
}

このプログラムも、前と同じようにサーバーを先に実行してください。次に、クライアントのプロジェクトを開いて実行します。

//sample6C.cs
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;

namespace lesoon10
{
    class sample6C : Form
    {
        public static string HOST = "localhost";
        public static int PORT = 10000;

        private TextBox tb1, tb2;
        private Button bt;

        private TcpClient tc;
        private StreamReader sr;
        private StreamWriter sw;

        static void Main(string[] args)
        {
            Application.Run(new sample6C());
        }
        public sample6C()
        {
            this.Text = "lesson10 sample6 Client";
            this.Width = 300; this.Height = 300;

            tb1 = new TextBox();
            tb2 = new TextBox();

            tb1.Height = 150;tb1.Dock = DockStyle.Top;

            tb2.Multiline = true;
            tb2.ScrollBars = ScrollBars.Vertical;
            tb2.Height = 150;
            tb2.Width = this.Width;
            tb2.Top = tb1.Bottom;

            bt = new Button();
            bt.Text = "送信";bt.Dock = DockStyle.Bottom;

            tb1.Parent = this;tb2.Parent = this;bt.Parent = this;

            Thread th = new Thread(this.run);
            th.Start(); //サーバーとやり取りするスレッドを起動します
            bt.Click += new EventHandler(bt_Click);
        }
        public void bt_Click(object sender, EventArgs e)
        {
            string str = tb1.Text;//ボタンを押したときに、サーバーに文字列を送信します
            sw.WriteLine(str);
            tb2.AppendText(str + "\n");
            sw.Flush();
            tb1.Clear();
        }
        public void run() //サーバーとやりとりするスレッドの処理です
        {
            tc = new TcpClient(HOST, PORT);
            sr = new StreamReader(tc.GetStream());
            sw = new StreamWriter(tc.GetStream());

            while (true)
            {
                try 
                {
                    string str = sr.ReadLine();//サーバーから文字列を読み込み続ける処理です
                    tb2.AppendText(str + "\n");
                }
                catch 
                {
                    sr.Close();
                    sw.Close();
                    tc.Close();
                    break;
                }
            }
        }
    }
}
サーバーの実行画面

クライアント実行画面

  ここでは、サーバーとクライアントともに、相手とのやりとりをするための処理を新しいスレッドとして起動しています。
  このため、このサンプルでは、複数のクライアントに同時に対応したりサーバーからのデータを受信しながらデータを送信することができるようになっています。スレッドは、ネットワークプログラムには欠かせない機能となっているのです。

コメント

タイトルとURLをコピーしました