Server と Client で通信

C# で TCP(Transmission Control Protocol) Server に Client から接続します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

TCP Server の説明

  1. 次のファイルを格納して下さい。
    /*************************************/
    /*★ Tcp Server Program    前田 稔 ★*/
    /*************************************/
    using System;
    using System.Net;
    using System.Net.Sockets; 
    
    class Server 
    { 
        public static void Main() 
        {
            TcpListener server = null;
            try 
            { 
                //サーバーを開始 
                Int32 port = 9999; 
                IPAddress localAddr = IPAddress.Parse("127.0.0.1"); 
                server = new TcpListener(localAddr, port); 
                server.Start(); 
    
                //接続待機 
                Console.WriteLine("接続待機中"); 
    
                //接続 
                TcpClient client = server.AcceptTcpClient(); 
                Console.WriteLine("接続されました"); 
                NetworkStream stream = client.GetStream(); 
    
                Byte[] bytes = new Byte[17]; 
                int i; 
    
                //メッセージを受信 
                while((i = stream.Read(bytes, 0, bytes.Length))!=0)  
                { 
                     String data = System.Text.Encoding.UTF8.GetString(bytes, 0, i); 
                     Console.WriteLine(String.Format("受信: {0}", data)); 
                } 
    
                client.Close(); 
            } 
            catch(SocketException e) 
            { 
                Console.WriteLine(e.Message); 
            } 
            finally
            {
                // Stop listening for new clients.
                server.Stop();
            }
        } 
    } 
    
    
    /*************************************/
    /*★ Tcp Client Program    前田 稔 ★*/
    /*************************************/
    using System;
    using System.Net.Sockets; 
    
    class Client 
    { 
        public static void Main() 
        { 
            try  
            { 
                //サーバーに接続 
                Int32 port = 9999; 
                TcpClient client = new TcpClient("127.0.0.1", port); 
     
                //サーバーにメッセージを送信 
                Byte[] data = System.Text.Encoding.UTF8.GetBytes("こんにちは"); 
                NetworkStream stream = client.GetStream(); 
                stream.Write(data, 0, data.Length); 
                Console.WriteLine("送信: {0}", "こんにちは"); 
     
                client.Close(); 
            } 
            catch (ArgumentNullException e) 
            {
                Console.WriteLine("ArgumentNullException: {0}", e);
            } 
            catch (SocketException e) 
            {
                Console.WriteLine("SocketException: {0}", e);
            }
    
        } 
    }
    
  2. C# では TCP での通信に次のクラスを使用します。
    1. TcpListener
      サーバー側で使用する、クライアントからの接続を受け付ける機能を提供するクラスです。
    2. TcpClient
      サーバー、クライアント共に使用する、実際に接続を行う機能を提供するクラスです。
    3. NetworkStream
      確立された接続から、データの読み書きを行うためのインターフェイスを提供するクラスです。
  3. Server 側のプログラムの手順です。
    Server はセッションを開設して Client からの接続を待ちます。
    1. ソケットを作る
    2. IP アドレスとポートを設定する
    3. 接続待ちする
    4. クライアントからの接続を受け付ける
    5. メッセージを受信する
  4. Server 側の Form.cs です。
    アプリケーションを特定するのに必要なポート番号とIPアドレスを設定します。
    server.Start() がサーバーを開始するコードです。
    server.AcceptTcpClient() で Client からの接続を待ちます。
    この時点でプログラムは接続されるまで先に進まなくなります。
  5. クライアントに接続されると、client.GetStream() 実行します。
    NetworkStreamは、確立された通信に対して、読み書きを行うインターフェイスになります。
    while ループでメッセージを受信します。
    受け取るデータがバッファより大きい場合があるためです。
    今回は8文字分(文字2バイト+ターミネーター1バイト)を確保しています。
    NetworkStream の Read メソッドはデータが送られてくるまで待機し、データが届いたら設定したバッファーの容量分だけデータを読み取り、 残っているデータのサイズを返すというメソッドです。
  6. While 文の中ではバイナリデータをテキストデータに変換して表示しています。
    ネットワーク上ではデータはバイナリ形式で流れることになります。
    従ってテキスト形式でやりとりするためには送信側でバイナリに変換し、受信側で再びバイナリ形式からテキスト形式に変換する必要があります。
    C# には文字列とバイナリの変換のために System.Text.Encoding というクラスが用意されているのでそれを利用します。
    サンプルコードでは日本語を扱えるように「UTF8形式」で変換するように指定しています。
    クライアントもこれに合わせる必要があります。
  7. client.Close() で Client から送られてきたメッセージの受信を終了します。

TCP Client の説明

  1. Client 側のプログラムの手順です。
    Client はセッションを開設している Server に接続してメッセージを送信します。
    1. ソケットを作る
    2. 接続相手を設定する
    3. 接続する
    4. メッセージを送信する
  2. Client 側の Form.cs です。
    IP アドレスを 127.0.0.1 に設定して、「こんにちは」という文字列を送信します。
    ポート番号を 9999 に設定していますが、これはサーバープログラムで指定したポート番号と同じです。
    new TcpClient(server, port) でサーバーに接続します。
    C# のクラス TcpClient を使用すると、たった一行でサーバーに接続することができます。
  3. Byte[] data にメッセージ(UTF8)をバイナリに変換してします。
    サーバー側でも UTF8 を使用するようにプログラムされていなければなりません。
  4. client.GetStream() で、確立した通信へのデータ書き込みのインターフェイスを取得します。
    stream.Write() でサーバーにメッセージを送ります。
    文字列の送信が終了したら client.Close() で通信を終了します。
  5. Cpp/CLI を使って同じようなプログラムを掲載しているので見比べて下さい。
    前田稔の超初心者のプログラム入門 から 「cpp/Server と Client で通信」を参照して下さい。
    また Win32 PAI を使ったプログラムも掲載しています。
    「C言語 Windows/Server と Client で通信」を参照して下さい。

【NOTE】

  1. 今回は Server と Client に一台の同じパソコンを使ってテストします。
    最初に Server Program を起動して Client の接続を待ち合わせます。
    次に Client Program を起動して Server に接続してメッセージを送信します。
  2. インターネットでは、コンピュータ同士がインターネットプロトコル(IP)を使って通信を行います。
    IPアドレスにはいくつかの特別な番号があります。
    1. INADDR_ANY (0.0.0.0)
      誰でもいいから
    2. INADDR_LOOPBACK (127.0.0.1)
      自分自身(というか、ネットワークに出さずに折り返し)
    3. INADDR_BROADCAST (255.255.255.255)
      ネットワークに繋がっている全コンピュータ
    4. INADDR_NONE (255.255.255.255) 存在しない
  3. 二台のパソコンを使って相互に通信するときは、パソコンに割り当てられた IP を調べて設定して下さい。
    パソコンに割り当てられたIPアドレスは ipconfig で確認できます。
    DNS(Domain Name Service) を使っている時などは、IPアドレスが変わることがあるので、実行時に確認して下さい。
    C:\>ipconfig
  4. ポートの設定
    IP アドレスを使ってコンピュータを指定して、ポートを使ってアプリケーションを指定します。
    電子メールサーバー、Webサーバー、FTPサーバーといったみんなが接続にくるようなアプリケーションサーバー(サービス)はその種類によって、決まったポートで待っています。
    例えば、電子メールの送信なら25番、受信が110番、FTPなら21番です。
    独自のネットワークサービスプログラムを作るのならこれらの番号以外を選ばなければなりません。
    一般的なテスト用には、5000番や12345番や9999番などが良く使われます。
  5. C/C++ プログラムは「超初心者のプログラム入門(C/C++)」から Server と Client で通信 を参照して下さい。
    パソコンがネットワークで接続されているか否かの確認は ping コマンドで行います。
    FTP サーバーを構築する を参照して下さい。
    最近では windows system やセキュリティソフトにより、ポートが閉じられている場合があります。
    通信が出来ないときは、コントロールパネルを開いて確認して下さい。

超初心者のプログラム入門(C# Frame Work)