[C#ネットワークプログラミングシリーズ]特集5:TCPプログラミング


前言
 
前のテーマの例はすべて応用層の上のHTTPプロトコルの紹介に基づいて、今本テーマは下の伝送層プロトコル--TCPプロトコルを紹介して、主に下のTCPプロトコルの仕事の過程とTCPプロトコルに基づく1つの簡単な通信プログラムを紹介して、以下は本テーマの本文を始めます.
 
一、TCPの作業過程
まずTCPは,接続向けで信頼性の高いバイトストリームベースの伝送層通信プロトコルである.TCPの作業過程は3つの段階に分けることができる:一、接続の確立;二、データを転送する.三、接続を切断して、以下はこの三つの過程についてそれぞれ紹介する.
1.1接続の確立
TCPの接続確立は電話をかけるように、私たちが電話をかけるとき、1つの番号の番号をダイヤルするのはすぐに接続できるわけではありません.その間に「ドゥドゥ」のコールプロセスがあります.これはTCPプロトコルの接続の確立段階のようなものです.TCPで作成したプログラムでは、まずTCP接続を確立する必要があります.TCPプロトコルの接続確立は3回の握手で完了し、以下はネット上で探したTCP 3回の握手の画像です.
 
この3回の握手について簡単に紹介します.
1回目の握手:接続を確立する時、クライアントはSYNパケット(seq=x)をサーバーに送って、そしてSYN_に入るSendステータス、サーバー確認待ち
2回目の握手:サーバーはSYNパケットを受け取って、必ず取引先のSYN(ACK=x+1)を確認しなければならなくて、同時に自分も1つのSYNパケット(SEQ=y)を送って、つまりSYN+ACKパケット、この時サーバーはSYN_に入りますRecvステータス
3回目の握手:クライアントはサーバのSYN+ACKパケットを受け取り、サーバに確認パケットACK(ACK=y+1)を送信し、このパケットの送信が完了し、クライアントとサーバはEstablished(確立)状態に入り、3回の握手を完了する.
3回の握手を簡単に理解するのは、1つの検査バッグを相手に送ってお互いに確認し、双方が確認の1つの信号を受け取ったとき、双方が接続を確立した(私たちが電話をかけたときのように、誰も話していないときは「もしもし」と言って、この「もしもし」と言った.つまり、相手の確認を望んでいます.ここでは双方が接続されていますが、ここでは3回の握手の過程をよりイメージ的に説明しています).
1.2データの転送
双方は接続を確立して、つまり双方が1つの通信通路を創立して(1つの橋のように、両端に1つの通路を創立して、橋で通信通路を比喩して主に最近1つのニュースがあるためです:ハルビン陽明灘大橋が崩壊する事件)、接続を創立した後に、私達が伝送しなければならないデータを相手に伝送しますここでは、データを転送する手順を簡単に説明します.
TCPでデータを転送する場合、データはバイトストリームとして転送され、クライアントがサーバ側と接続を確立すると、送信側はまず送信データをバイトストリームに変換してから相手に送信する必要があり、データを送信する場合、プログラムによってデータストリームをTCPの送信バッファに次々と書き込むことができ、その後、TCPは、送信バッファから一定量のデータを自動的に抽出し、TCPメッセージセグメントを構成してIP層に送信し、IP層(すなわち、ネットワーク層)の下のネットワークインタフェースを介して送信する.受信側は,IP層からTCPメッセージセグメントを受信した後,受信バッファに一時保存し,受信バッファのデータをプログラムにより順次読み出し,相互通信の目的を達成する.(簡単に言えば、送信側がデータストリームに変換してデータストリームを送信バッファに格納し、転送層の下位層のプロトコルが送信バッファからデータを読み出してデータを送信し、受信側が下位層からデータを受け取って受信側のバッファにデータを格納し、私たちが書いたプログラムはバッファからデータを順次読み出して表示するだけで、クライアントで私たちがコードを書くことは、Writeを送信側のバッファに書き込み、サーバ側(受信側)がRead方式で自分のバッファでデータを読み取ることです.一言で言えば、TCPの伝送はデータの書き込み-読み取り操作です.括弧の中の内容は私個人が理解しているだけなので、理解しやすいと思います.TCPに触れ始めたばかりの友达にはこのように理解して、それからもう一言拡張することができます.
1.3接続解除
データを送信した後、最後に接続を切断しました.次はネット上で切断された接続の画像です(接続を切断するには4回の握手が必要です):
 
TCPの仕事の過程は上の3つの過程に分けて、TCPプログラミングは上層の応用プログラミングの基礎として、前のテーマの中でHTTPプロトコルに基づくWebサーバー、Webブラウザのようで、その伝送層はすべてTCPプロトコルで伝送して、FTP(ファイル伝送プロトコル)、IMAP(インタラクティブメールアクセスプロトコル)POP 3(郵便局プロトコルの3番目のバージョン)とSMTP(単純メール転送プロトコル)のネットワークアプリケーションは、その転送層がUDPなどの他の転送層プロトコルではなくTCPプロトコルを用いている.
 
 
二、TCPプロトコルに基づく簡単な通信プログラム
ここでは、クライアントとサーバ間の通信プログラムを簡単に実現しました.コアコードは次のとおりです.
クライアント接続サーバ側コード:

 private void btnConnect_Click(object sender, EventArgs e)
        {
            //           ,   
            Thread connectThread = new Thread(ConnectToServer);
            connectThread.Start();
        }

        //        ,       
        private void ConnectToServer()
        {
            try
            {
                //     
                statusStripInfo.Invoke(showStatusCallBack, "    ...");
                if (tbxserverIp.Text == string.Empty || tbxPort.Text == string.Empty)
                {
                    MessageBox.Show("        IP      ");
                }

                IPAddress ipaddress = IPAddress.Parse(tbxserverIp.Text);
                tcpClient = new TcpClient();             
                tcpClient.Connect(ipaddress, int.Parse(tbxPort.Text));               
                
                //     
                Thread.Sleep(1000);
                if (tcpClient != null)
                {
                    statusStripInfo.Invoke(showStatusCallBack, "    ");
                    networkStream = tcpClient.GetStream();
                    reader = new BinaryReader(networkStream);
                    writer =new BinaryWriter(networkStream);
                }
                 

            }
            catch
            {
                statusStripInfo.Invoke(showStatusCallBack,"    ");
                Thread.Sleep(1000);
                statusStripInfo.Invoke(showStatusCallBack,"  ");
            }
        }

クライアントがメッセージを送信するコード:
//     
        private void btnSend_Click(object sender, EventArgs e)
        {
            Thread sendThread = new Thread(SendMessage);
            sendThread.Start(tbxMessage.Text);
        }

        private void SendMessage(object state)
        {
            statusStripInfo.Invoke(showStatusCallBack, "    ...");
            try
            {
                writer.Write(state.ToString());
                Thread.Sleep(5000);
                writer.Flush();
                statusStripInfo.Invoke(showStatusCallBack, "  ");

                tbxMessage.Invoke(resetMessageCallBack, null);
                lstbxMessageView.Invoke(showMessageCallback, state.ToString());
            }
            catch
            {
                if (reader != null)
                {
                    reader.Close();
                }
                if (writer != null)
                {
                    writer.Close();
                }
                if (tcpClient != null)
                {
                    tcpClient.Close();
                }

                statusStripInfo.Invoke(showStatusCallBack, "     ");
            }
        }

サーバ側は、クライアント要求のリスニングを開始するコードを受け入れます.

 //     
        private void btnStart_Click(object sender, EventArgs e)
        {
           
            tcpLister = new TcpListener(ipaddress,Port);
            tcpLister.Start();
            //            
            Thread acceptThread =new Thread(acceptClientConnect);
            acceptThread.Start();
        }

        //     
        private void acceptClientConnect()
        {
            statusStripInfo.Invoke(showStatusCallBack,"    ");
            Thread.Sleep(1000);
            try
            {
                statusStripInfo.Invoke(showStatusCallBack,"    ");
                tcpClient = tcpLister.AcceptTcpClient();
                if (tcpLister != null)
                {
                    statusStripInfo.Invoke(showStatusCallBack,"     ");
                    networkStream = tcpClient.GetStream();
                    reader = new BinaryReader(networkStream);
                    writer = new BinaryWriter(networkStream);
                }
            }
            catch
            {
                statusStripInfo.Invoke(showStatusCallBack, "    ");
                Thread.Sleep(1000);
                statusStripInfo.Invoke(showStatusCallBack, "  ");
            }
        }

実行結果を見てみましょう.まずサーバを起動してから、リスニングを開始します.スレッドは接続要求の場所に受信されるまでブロックされます.
次にクライアントを実行し、IPアドレスとポートにサーバー側のIPアドレスとポート番号を入力し、サーバーに接続するボタンをクリックした後のインタフェースは以下の通りである.
受信ボタンと送信ボタンによって双方の通信を実現し、実現インタフェースは以下の通りである.
 
三、まとめ
ここまでこのテーマの内容は多くなくて、本テーマは主にTCPプロトコルの仕事の過程とネットプラットフォームの下で1つの簡単な通信のプログラムをカスタマイズすることに基づいて紹介して、本テーマがあれらに初めてTCPプロトコルに接触する友达にいくつか助けを与えることができることを望んで、(大牛达は直接フラッシュすることができる)后のテーマで私はみんなとUDPのプログラミングを分かち合って、UDPのプログラミングを终えて后でこの2章の内容を结び付けて1つのQQのインスタントチャットのツールを実现して、これらがみんなに役に立つことを望んで、もしみんながどんな问题と兴味のあるテーマが理解する必要があるならば、私に伝言を残して、后の文章はすべてみんなと分かち合います.
 
 
见て助けてくれると思う方は、お勧めしてください.続けていく力も与えてくれます.もし皆さんが何か兴味のあるテーマがあれば、伝言を残して教えてください.私は勉强を通じて、次々と皆さんと分かち合います.