【C#】ソケット通信(Socket通信) クライアント編

スポンサーリンク

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

クライアントについて説明していきますが、

サーバー編も書いていきますが、大きく内容が違うわけではありません。

ただ立場が違うので、自分がどっちを作りたいかで見てください。

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/Portです。

変動に対応できるように設定できるようにしましょう。

【確認】ボタンは、IPが存在しているか確認する為に作りました。(余談として話します)

【送信】ボタンでは、下記流れで実施します。

●サーバー接続
●コマンド送信
●(サーバーからの)コマンド受信
●サーバー切断

クライアントを作ろう 接続/切断

まずは接続しましょう。

using System.Net.Sockets;
TcpClient tcp;  //定義

pubic void OpenTcpCliant(string ipadd, int port)
{
  tcp = new TcpClient(ipadd, port);
}

そして、切断です。

public void CloseTcpCliant()
{
   tcp.Close()
}

実際に動作させます。

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

■IPが在りえない設定の場合■
■IPが間違っている場合■  ※タイムアウトまでフリーズ
■サーバーが立ち上がっていない■

上記3つが在りえそうな例外です。(SocketException)

クライアントを作ろう 送信/受信

送信を作ります。

private int Send_TCP(string tmp,out string rcv)
{
  using (NetworkStream ns = tcp.GetStream())
  {
    ns.ReadTimeout = 1000;
    ns.WriteTimeout = 1000;
    Encoding enc = Encoding.UTF8;
    byte[] sendBytes = enc.GetBytes(tmp + '\n');
    ns.Write(sendBytes, 0, sendBytes.Length);

    //受信
    Recieve_TCP(ns, out rcv);
    ns.Close();
  }
  return 0;
}

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

送信の関数の中に入れています。

続いて受信です。

private int Recieve_TCP(NetworkStream ns, out string rcv)
{
  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();
  }
  return 0;
}

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

メモリーストリーム(MemoryStream)を使って書き出します。

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

サーバーへの接続/切断/送受信を作ったので、

【送信】ボタンの中身を作ります。

private void btnSend_Click(object sender, EventArgs e)
{
  string tmp;
  int hoge;
  Get_TCPServer(out tmp, out hoge);

  //オープン
  Open_TCP(tmp, hoge);

  //送受信
  Send_TCP(txtSend.Text, out tmp);
  lblRecieve.Text = tmp;

  //クローズ
  Close_TCP();
}

関数: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();
  }
}

動作確認をしてみましょう。

サーバーのソフトが立ち上がっていない為、うまくはいきませんwww

次回は、サーバー側を作ってみましょう。

【余談】IPアドレスの有無確認

IPアドレスを確認する時に、【コマンドプロンプトでping】を使うと思います。

pingとは、
対象のコンピュータとネットワークでつながっているか確認するときに使うコマンド

C#でもpingクラスが準備されている為、使ってみましょう。

using System.Net.NetworkInformation;

private bool Send_Ping(string ip)
{
  //Pingのインスタンス生成
  Ping sender = new Ping();

  //ping送信
  PingReply reply = sender.Send(ip, 50);
  return (reply.Status == IPStatus.Success) ? true : false;
}

では、【確認】ボタンの処理を作りましょう。

private void btnCheck_Click(object sender, EventArgs e)
{
  //検索するIPアドレスを取得する
  string tmp;
  int hoge;
  Get_TCPServer(out tmp, out hoge);

  //pingの送信
  bool res = Send_Ping(tmp);

  //結果に応じて、表示の変更
  string mes = (res == true) ? "存在確認OK" : "接続不可";
  MessageBox.Show(mes);
}

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

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

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

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

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

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

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

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

まとめ

今回はクライアント側を作りました。

サーバーが存在しないと確認できない為、次回はサーバー側を作りましょう。

コメント

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