今日は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/ポートに誤りがあった場合、例外が発生します。
在りえそうな例外です。(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
業務でプログラミング(C#/VB/Python)を作っている。
挫折を何回も繰り返し、幾度の壁を乗り越えてきた。
乗り越えてきた事を忘れないように記録に残す。
同じ思いをしている人への情報提供になれたらと思う。
基本は初心者に向けたプログラムの情報を提供する。
コメント