私たちの前で、その上にサーバとクライアント、およびUDPベースのTFTPサーバアプリケーションを実現しています。次は、私たちは、広くアプリケーションのすべての種類を使用したのと同じTCPプロトコルを実現します。
1 、TCPの簡潔
TCP(伝送制御プロトコル伝送制御プロトコル)は、IETF RFC 793によって定義されたバイトのストリームに基づいて、接続指向の、信頼性の高いトランスポート層プロトコルです。コンピュータネットワークの簡略化されたOSIモデルでは、トランスポート層で指定された第4層の機能を完了し、ユーザーデータグラムプロトコル(UDP)は、同じ層内の他の重要な伝送プロトコルです。インターネットプロトコルスイート(インターネット・プロトコル・スイート)で、TCP層、IP層の上のアプリケーション層の下の中間層に位置しています。多くの場合、あなたは配管の接続などの異なるホスト間で信頼性の高いアプリケーション層、などを、必要がありますが、IP層自体は、このような流れのメカニズムを提供していませんが、信頼性の高いパケットスイッチング、TCPプロトコルアプリケーション要件のまさにこの欠如を提供していません。
アプリケーション層ゲートウェイは、8ビットによって表されるデータストリームと、送信用のTCPレイヤを送信バイト、TCPデータストリームは、適切な長さのセグメントに分割されます。IP層にTCPパケットの結果の後に、それによってネットワークパケットを介してTCPレイヤエンティティの受信側へ。発生していないTCPパケット損失を保証するために、各パケットにシーケンス番号を与えるだけでなく、シリアル番号が順次パケット受信エンティティの受信側に伝送することを保証します。次に、受信側が正常に受信したパケットのエンティティは、対応する肯定応答(ACK)を返送する;妥当往復時間内に送信側エンティティは、(RTT)肯定応答が受信されない場合、対応するデータパケットがあったと想定されます再送を失われます。チェックサムは、データの正確性を確保するために、送信のために計算され、受信され、データにエラーがあるかどうかをチェックする機能を有するTCPチェックサム。次のようにTCPプロトコルパケットの構造は次のとおりです。
各TCPパケットセクションの意味:
(1 )送信元ポートと宛先ポート
送信元および宛先ポートは、2つのバイトを占有します。セグメントのホストから来て、どこに転送することです知らせるために使用します。TCP通信は、クライアントは通常、自動的にアプリケーションと、よく知られたサービスのポート番号を使用してサーバーに応じて、一時的なポート番号を選択するために、システムを使用する場合。
(2 )SEQ ID NO
配列番号4は、バイト。TCPはバイトストリームトランスポートの各バイトは、TCPコネクションが順番に番号が付けられ、バイト指向のストリームです。シリアル番号は、32ビットで表現されているので、最大値は、電源32にするときゼロに次のシーケンス番号バック最大数の増加2。これは、データの4ギガバイトにTCPプロトコルを番号付けすることができる、一般的に、ときシリアル番号は、古いデータのシリアル番号が既にフィニッシュラインのネットワークに到達したか、失っていたことを確認するために繰り返し使用することができます。
(3 )確認応答番号
確認番号は4バイトです。彼は相手がレポートの次のシーケンス番号値のセグメントを受け取るという期待を表明しました。すべてのデータは、以前の番号が正しく受信されていることを示しています。ACKフラグが1つだけ有効である場合にのみ、確認番号。
(4 )TCP ヘッダ長
TCPヘッダ長はまた、半バイト(4ビット)を表すオフセットデータと呼ぶことにします。これは、TCPセグメントの先頭のデータがTCPパケットの先頭から遠く離れていることを指摘しました。LWIPは、TCPデータ構造を理解するときには、この値は非常に有用であることがわかります。
(5 )TCPのフラグ
TCPフラグ、合計6つ、合計6つを占めました。のみ0と1の全ての値は、それぞれ、異なる意味を表現します。
- URGのフラグ緊急ポインタが有効を示すときURG = 1のとき、緊急フラグと呼ばれ、。それはないため配送まで、元の線で、できるだけ早く転送する必要があり、このセグメントデータでの緊急事態があることを伝えます。URGフラグがヘッダ「緊急ポインタ」フィールドと併せて使用されます。
- ACKのフラグ認定フラグと呼ばれ、ACK = 1は、確認番号が有効です。ACKフラグとTCPセグメントは、「セグメントを確認した。」のように一般的に知られています TCP接続が確立された後、伝送のすべてのセグメントがACKを1に設定しなければならないことを提供します。
- PSHのフラグと呼ばれるプッシュフラグPSH = 1時間、高優先度のセグメントを示す場合、受信したTCPは、出荷前に充填される全体のTCPバッファを待つことなく、すぐに可能な限り受信側アプリケーションにプッシュしなければなりません。
- RST フラグ表現重大なエラーが接続TCPで発生したRST = 1、接続を解除し、再確立する必要性リセットフラグと呼ばれます、、。一般的にTCPセグメントのRSTフラグを運ぶことが知られている「リセットセグメント」です。
- SYNのフラグ SYN = 1は、この接続要求パケットのセグメントであることを示す場合、同期フラグ、時間と呼ばれます。一般セグメント運ぶTCP SYNフラグとして知られている「同期セグメント」を 最初のパケット内のTCPスリーウェイハンドシェイクで接続が確立されると、シリアル番号を同期するために使用される同期セグメントです。相手が接続を確立することに同意した場合は、応答セグメント操作SYN = 1、ACK = 1にする必要があります。
- FIN フラグ = 1 FINは、これはデータセグメントの送信者が送信されたことを示し、およびTCP接続の解放のために終了フラグと呼ばれます。FINとして一般セグメントを運ぶことが知られている「セグメントの終わり。」TCPコネクションのリリースでは4は手を振ったし、彼らはこのフラグを使用します。
(6 )ウィンドウサイズ
ウィンドウサイズは2つのバイトを占有します。フィールドは現在、データの量が、他の側はデータのバイトローカルTCPが受信バッファをどのように多くのお互いを伝えるためにそれを送信できるようにすることが明らかにされた相手がデータを送信する速度を制御することができますので、対応することができます。新聞のヘッダセグメント確認番号から数えて、ウィンドウサイズの値を参照し、データの送信量の現在の受信者は、他のを可能にしました。
(7 )チェックサム
2つのバイトをチェックサム。送信者によって満たされ、受信機はTCPセグメントのCRCアルゴリズムTCPセグメントが送信中に破損しているかどうかを確認行い損傷した場合、それは破棄されます。試験は、2つの部分の重要な保証信頼性の高いTCPトランスポートであり、ヘッダとデータを、範囲から成ります。
(8 )緊急ポインタ
緊急ポインタは2つのバイトを占有します。URG = 1の場合にのみ意味のある、それは緊急データの新聞セグメントのバイト数を示します。URG = 1のとき、送信TCP緊急データセグメントは、新聞データの先頭に挿入されて入れて、データの後に緊急データがまだ正常なデータです。したがって、緊急ポインタは、セグメント内の緊急データの末尾の位置を示します。
2 、TCPのサーバ設計
私たちは、TCPプロトコルとメッセージ形式の簡単な説明を行っているし、我々は、RAW APIアプリケーションに簡単なTCPサーバーを使用して、LWIPプロトコルスタックを結合します。
2.1 、TCP 関連のRAWのAPIの機能
私たちは、TCPサーバーの実装を開始する前に、我々は最初のTCPのものと関連したRAW API関数のlwIPを見てみましょう。そして、単にその機能を見てください。
2.1.1 確立するTCP コネクションAPIの機能を:
2.1.2 送信TCPのデータAPIの機能:
2.1.3は、受信したTCP データAPIの機能を:
2.1.4 、TCP ポーリングAPIの機能:
2.1.5 、決算及びアボートTCP コネクションAPIの機能:
2.2 、TCP ワークフローサーバー
私たちは、TCPのAPI関数は、TCPサーバーを使用して、これらの機能を実現するためにどのようにして、関与を学びましたか?私たちは最初に簡単に基本的なプロセスを説明します。
2.2.1 、新しい制御ブロック
機能は、TCP制御ブロックを作成します()tcp_new使用してください。
2.2.2 結合制御ブロック
サーバーの場合は、新しい制御速い、ローカルIPおよびクライアントへの接続を容易にするために、制御ブロックに結合するポートが必要。
2.2.3 、リスナー制御ブロック
tcp_listen機能を使用して、サーバーのために、我々は、明示的な呼制御機能ブロックtcp_listenは、クライアントからの接続要求を待って、リスニング状態に入るようにする必要があります。
2.2.4 接続を確立します
クライアント接続要求が正常に確立されると、サーバはハンドラを呼び出すため実際には、我々は、受信ハンドラを登録するには、すぐにtcp_accept機能を必要に応じて、サーバーのリスニングステートにtcp_listen関数を呼び出します。
2.2.5 、受信して処理するデータ
一旦接続されると、コールバック関数の呼び出しは、登録されたハンドラが完了したことを受けtcp_recv受け入れます。サーバーの場合、クライアントはデータや運用要件を受け取り、処理のためにコールバックを呼び出します。実際には、これは複雑なプロセスである:、データ、最初の通知更新受付画面(使用tcp_recved関数)を受信する処理と、(tcp_write関数を使用して)データを送信した後、データが最終的に送られてきた(tcp_sent関数を使用して)データをクリアし、正常に送信され(関数tcp_closeを使用して)接続を閉じます。
このフローチャートは以下のように表されます:
フローチャートにおいて、我々は、あらゆる面で使用される主な機能は、他の多くの機能を使用するが、記載されていないリストソースコードに興味ができるフリーアクセスがあるか、またはマニュアルを参照してください。
2.3 、一般的に使用されるポート
UDPが使用するTCPポートは、いくつかの異なるが同じの多くを持っています。操作を容易にするために、我々は、ファイルに保存されているマクロ定義を形成するための共通ポートを持っています。下に記載されている今、一般的に使用されるポートは、我々は我々の操作は次のポートを使用して達成することです。
ここでは、単純なTCPサーバを設計し、私たちはただ、それがどんな複雑なアプリケーションを設定していないので、私たちはTCPエコープロトコルポートを使用することにしました。
3 、TCPのサーバーの実装
まず、初期TCPサーバーを:私たちは、私たちが達成するために3つの部分に分割されます、ワークフローTCPサーバーを分析しました。どちらのコードは次のとおりです。
1 / * TCPサーバ初期化* / 2 空隙 Tcp_Server_Initialization(ボイド) 3。 { 4。 構造体 tcp_pcb * tcp_server_pcb; 5 。6 / * tcp_pcbのTCPサーバに構造を割り当てる* / 7。 tcp_server_pcb = tcp_new(); 8 。9 / * バインドローカル端末番号とIPアドレス* / 10 tcp_bind(tcp_server_pcb、IP_ADDR_ANY、TCP_SERVER_PORT); 11 12れている / * tcp_server_pcbリスニング前に作成された構造* / 13である tcp_server_pcb = tcp_listen(tcp_server_pcb); 14 15 / * 初期化構造受信コールバック関数* / 16 tcp_accept(tcp_server_pcb、TCPServerAccept); 17 }
tcp_accept_fn型でコールバック関数が、TCPサーバの実装によって受信その後、リスナーは制御ブロックのフィールドを受け入れるように登録しました。呼接続がサーバー上で確立された新しいカーネルがあります。この機能では、我々は非常に重要な機能を実装する必要があり、登録済みのTCPサーバは、データ処理機能を受け取ります。
1 / * この関数は、接続するクライアントに呼び出されたときにTCPサーバは、コールバック関数を受信* / 2 静的 err_t TCPServerAccept(ボイド *のArg、構造体 tcp_pcb * PCB、err_t ERR) 。3 { 4は、 / * コールバックを受信するために登録* / 5 tcp_recv(PCB、TCPServerCallback) 。6 。7 戻りERR_OK; 8 }
最後に、言うまでもない具体的な実現のTCPサーバ機能を実現することです。この機能は、TCPサーバーは、データ処理機能を受け取ると、我々はすでに登録されているという事実です。この関数は、tcp_recv_fnタイプです。我々は機能とを持つオフ機能に完全に依存しています何を達成したものだから、TCPサーバの最も重要な機能を実現するためにTCPサーバーをRAWのAPIを使用しています。
1 / * TCPサーバデータ処理サーバのコールバック* / 2 静的 err_t TCPServerCallback(ボイド *のArg、構造体 tcp_pcb * PCB、ストラクト PBUF * tcp_recv_pbuf、err_tのERR)を 3。 { 4。 構造体 PBUF * tcp_send_pbuf; 5 CHAR echoString [] = " このクライアントコンテンツエコーはIS:\ R&LT \ N- " ; 6 。7 IF(!tcp_recv_pbuf = NULL) 。8 { 9 / * 更新ウィンドウ受信* / 10 tcp_recved(PCBを、tcp_recv_pbuf-> tot_len)。 。11 12は、 / *が送信構造に、受信したデータのコピー* / 13である tcp_send_pbuf = ; tcp_recv_pbuf 14 tcp_write(PCB、echoString、strlenを(echoString)、1。); 15 / * 受信されたデータは、その後、アウト転送される* / 16 tcp_write (PCB、tcp_send_pbuf->ペイロード、tcp_send_pbuf-> LEN、1。); 17 18は pbuf_free(tcp_recv_pbuf) 。19 tcp_close(PCB) 20である } 21れる 他 IF(ERR == ERR_OK) 22は 、{ 23が リターンtcp_close(PCB) 24 } 25 26 リターンERR_OK。 27 }
あなたはこれに基づいて、より高度なアプリケーション層プロトコルを拡張することができ、より複雑な機能が必要な場合は、ここでは唯一、単純なサーバーのオペレーティング・ループバック機能を実現します。
4 おわり
この記事に基づいて、我々は、単純なTCPサーバ・アプリケーションを実現するためにLWIP。コールバック関数の実装によって、UDPの全プロセスと実装は、本質的に類似しました。私たちは、TCPコネクションのクライアントソフトウェアのテスト、何の問題を使用します。あなたがなどのModbus TCP、としてTCPサーバーに基づいて、より複雑なアプリケーションを、実現したい場合にのみ、その上にコールバック関数に応じて機能を実装する必要があります。
ようこそ懸念: