【C#】ソケット通信(Socket通信) サーバー編

スポンサーリンク

今日はSocket通信についてです。

サーバーについて説明していきますが、

クライアント編で説明してる部分と被っていますが、

『クライアント編』を見てねって言うと、たらいまわし感が出るので、

分かってる部分は読み飛ばしてください。(最初の方はコピペですwww)

Socket通信とは

インターネットはTCP/IPと呼ぶ通信プロトコルを利用しますが、
そのTCP/IPを プログラムから利用するには、
プログラムの世界とTCP/IPの世界を結ぶ特別な 出入り口が必要となります。
その出入り口となるのがソケット (Socket)であり、
TCP/IPのプログラミング上の大きな特徴となっています。 
このため、TCP/IP通信をソケット通信と呼ぶこともあります。

うぅ~ん。。。難しい説明ですね。。。

簡単に説明すると、

インターネットができるのは、ソケット通信のおかげという事になります。

いゃいゃざっくり過ぎるだろうっっ!!って思うかもしれませんが、

極論そういう事なのです。

サーバーとクライアントとは

サーバーとクライアントを理解しましょう。

基本的なイメージでは、

サーバーがあって、

サーバーに接続するクライアントがいるイメージになります。

基本ソフトを作る側の人間は

クライアント側のソフトを作る事の方が多いとは思います。

言葉の意味を調べましょう!!

クライアント:サービスを利用するコンピュータ
サーバ   :サービスを提供するコンピュータ

分かりそうで分からないこの説明。。。

例え話をします。

A君は、会議中、わからない言葉が出てきた。
質問するのを恥ずかしいので、スマホで、Googleで検索をした

簡潔にまとめると【A君はGoogleで検索をした】です。

ここでいう【A君(クライアント)】【Google(サーバー)】となります。

質問者(クライアント)と回答者(サーバー)の関係です。

接続について

つぎに、つなげるケーブルについて説明します。

接続するのは、【LANケーブル】です。

LANケーブルにも種類があるので、触れておきます。

※現在では、自動判別機能(AutoMDI/MDI-X)によりほぼ知識不要になっている

  

LANケーブルの種類は2種類あります。

ストレートケーブル】【クロスケーブル】です。

クロスケーブルは、通信規格や結線規格によって、ピンアサインは違います。

使い分けをどうするかというと、

異なる機器同士を接続する時:ストレートケーブル (パソコンとHub/パソコンと通信機器)
同じ機器同士を接続する時 :クロスケーブル (パソコンとパソコン/HubとHub)

ただし、現在では、自動判別機能(AutoMDI/MDI-X)により、

【ストレートケーブル】しか使いませんが、

古いパソコンや古いHubを使うときは気をつけましょう。

サーバーを作ろう GUI

まずは、操作画面です。

サーバー側のソフトなので、自分のIPを取得すればいいと後から後悔。。。

IPアドレスは、サーバーのIPアドレスを設定します。

ポートに関しては、 0 ~ 65535の間で設定しますが、すでに使用されているポートもあります。

■ウェルノウンポート:0~1023
■登録ポート:1024~49512
■ダイナミック/プライベートポート:49513~65535

ソフトウェアで使うのは8000番台が多いですが、

ダイナミック/プライベートポートは確実に使用されていません。

【起動】ボタンで、サーバーを起動させます。

●サーバー起動[リスナー開始]
●(クライアントから)コマンド受信
●(クライアントへ)コマンド送信
●サーバー切断[リスナー終了]

サーバー[リスナー]を作ろう 開始/終了

まずは接続しましょう。

using System.Net.Sockets;
TcpListener listener = null;

private void Start_TCPServer()
{
  string tmp;
  int hoge;
  Get_TCPServer(out tmp, out hoge);

  IPAddress ip = IPAddress.Parse(tmp);  //IPアドレス型にキャスト(型変換)
  listener = new TcpListener(ip, hoge);  //TCPListenerインスタンス生成
  listener.Start();
}

関数:Get_TCPServerでは、GUI上の設定を取得しています。

IPアドレスの設定のNumericUpDownには、

命名規則を決めてコントロール名から取得するようにしました。※クライアントでも同じ

private void Get_TCPServer(out string ipadd, out int port)
{
  port = (int)nudport.Value; //ポートは簡単

  ipadd = "";
  //IPの取得(IPパラメータ4つ分取得)
  for (int n = 0; n < 4; n++)
  {
    //コントロール名から設定を取得
    NumericUpDown nud = (NumericUpDown)this.Controls["nudIP" + (n + 1).ToString()];
    if (nud == null)
    {
      MessageBox.Show("こんとろーる取得失敗");
      return;
    }
    //最初だけカンマ無し
    ipadd += (n == 0) ? nud.Value.ToString() : "." + nud.Value.ToString();
  }
}

そして、切断です。

public void Stop_TCPServer()
{
   listener.Stop();
}

実際に動作させます。

サーバーのIP/ポートに誤りがあった場合、例外が発生します。

■IPアドレスに誤りがある

在りえそうな例外です。(SocketException)

サーバーを作ろう 送信/受信

サーバー側は、クライアントからコマンドを受信してから動作します。

private int Recieve_TCP(out string rcv)
{
  tcp = listener.AcceptTcpClient();
  using (NetworkStream ns = tcp.GetStream())
  {
    ns.ReadTimeout = 10000;
    ns.WriteTimeout = 10000;
    Encoding enc = Encoding.UTF8;
    using (MemoryStream ms = new MemoryStream())
    {
      byte[] resBytes = new byte[256];
      int resSize = 0;
      do
      {
        resSize = ns.Read(resBytes, 0, resBytes.Length);
        if (resSize == 0)
        {
          Console.WriteLine("データなし");
          break;
        }
        ms.Write(resBytes, 0, resSize);
      } while (ns.DataAvailable || resBytes[resSize - 1] != '\n');
      rcv = enc.GetString(ms.GetBuffer(), 0, (int)ms.Length);
      ms.Close();

      //返信(送信)
      string mes = "Thanks";
      byte[] sendBytes = enc.GetBytes(mes + '\n');
      ns.Write(sendBytes, 0, sendBytes.Length);
      ns.Close();
    }
  }
  return 0;
}

受信、送信方法は、クライアントの時と同じです。

受信も同じネットワークストリーム(NetworkStream)上で実施しないといけなかったので

ネットワークストリーム(NetworkStream)上にある受信データを

メモリストリーム(MemoryStream)に書き出します。

送信はネットワークストリーム(NetworkStream)で送信します。

クライアントを作ろう 一連動作

必要な機能は作れたので、【起動】ボタンの一連動作を作りましょう

private void btnStart_Click(object sender, EventArgs e)
{
  do
  {
    Start_TCPServer();

    string tmp;
    Recieve_TCP(out tmp);
    lblRecieve.Text = tmp;  //受信内容表示
    Application.DoEvents();

    Stop_TCPServer();
  } while (lblRecieve.Text.Trim() != "END");  //ENDを受信するまで起動する
}

今回ので、サーバーとクライアントが揃いました。

実際に起動させてみましょう。

【余談】IPアドレスの設定確認/方法

windows10の場合のIPアドレスの確認方法です。

[スタート]を右クリック→検索

【ネットワークの状態】を検索

【アダプターのオプションを変更する】をクリック

対象のLANポートを右クリック→[プロパティ]

→[インターネットプロトコルバージョン4]をダブルクリック

現在のIPアドレスを確認する事ができます。

まとめ

今回はサーバー側を作りました。

前回クライアント側を作ったので、併せて動作確認しましょう。

パソコンは1台あれば大丈夫です。

自分のIPでサーバーを立ち上げ、

クライアントは同じIPに向かって送信させましょう。

独り言をしゃべってる感じになりますwww

コメント

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