今日は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/ポートに誤りがあった場合、例外が発生します。



上記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アドレスを確認する事ができます。
まとめ
今回はクライアント側を作りました。
サーバーが存在しないと確認できない為、次回はサーバー側を作りましょう。

業務でプログラミング(C#/VB/Python)を作っている。
挫折を何回も繰り返し、幾度の壁を乗り越えてきた。
乗り越えてきた事を忘れないように記録に残す。
同じ思いをしている人への情報提供になれたらと思う。
基本は初心者に向けたプログラムの情報を提供する。
コメント