通信ソケットプログラミング--tcp

通信のTCPフロー:接続指向の、信頼性の高い伝送、指向バイトストリーム

クライアント(クライアント):

  1. ソケットを作成します。
  2. アドレスバインディング(アクティブお勧めしません)
  3. サーバへの接続要求を発行
  4. 送信/受信データを
  5. ソケットを閉じ

サーバー(サーバー):

  1. ソケットを作成します -ソケット構造体を作成するために、カーネル内のカードとの接触を確立します
  2. ソケットのための情報がバインドされたアドレスである -受信バッファに私を置く-データは私に処理するものオペレーティングシステムに伝えます
  3. スタートリスニング -両当事者は、データが送受信されていることを確実にする能力-クライアントとサーバ間の通信は、最初のTCP接続を確立する必要があります-接続要求を正当化叫びの受信を開始することができ、オペレーティングシステムに指示します。
    サーバがクライアントからの接続要求を受信すると、接続を確立するプロセスはカーネルで行われます。
    接続要求が到着した後の最初のソケットにのみ、新しい接続要求を受信するための新しいソケットサーバをTCP、クライアントとのその後の通信のために作成した、新しいソケットを作成し、
  4. 新しく作成されたオペレーティングへのハンドル取得するソケットのソケットサーバープログラム
    サーバープログラムは、新しいソケットの作成、カーネルに新たな接続を受ける
    ソケット操作ハンドルカーネル新しく作成されたサーバプログラムを
    、この操作GETのサーバ側プログラムにクライアントハンドルと通信
  5. サーバーは、新しいソケットを介してクライアントとの間でデータ通信を行うことができ
    、データ/送信データ受信
    データ通信時にTCPを、それは誰でも(この時間は、接続が確立されているため)に送信することができます
  6. 閉じるソケット:リソースの解放

TCPソケット・インタフェースは、通信を説明しました。

ソケットを作成するには1、

int socket(int domain,int type,int protocol)

(アドレスフィールドAF_INET、ソケットタイプのSOCK_STREAM、プロトコルタイプIPPROTO_TCPのゴー)

2、バインディングアドレス情報

int bind(int sockfd,sockaddr *addr,socklent_len);

3、リスニングを開始

int listen(int sockfd,int backlog);

バックログ:ノードのキューの最大数保留中のカーネルのTCP接続 - サーバが同じクライアント接続要求を受信できる時間の量を決定します

ネットワーク攻撃:SYNフラッド攻撃:
悪質なホストは、サーバーが要求ごとに、まだであればソケットを確立するために、サーバーへの接続を確立するために多数の要求を送信し続け、今では、リソースのサーバーのクラッシュを実行します

4、サーバプログラムは、新しく作成されたソケット操作へのハンドルを取得します

int accept(int sockfd;struct sockaddr *addr,socklen_t len);

このステップは、カーネルから機能が新しい接続を受信し続けることができます座席を解放し、取得ソケット接続キューを完了したで
、買収によって作成された新しい接続のための新しいソケットソケットサーバソケットを指定する-記述:数sockfdリスニングソケットれる-ソケットは、キューがキューで聞く
のaddr:クライアント情報のアドレス
でlen:入力・出力パラメータ:指定しますが、アドレス情報を取得したい、だけでなく、実際に取得したアドレスの長さについての情報を入手長
戻り値:リターンに対する権利を新しく作成されたソケットハンドルの具体的な操作-ファイルディスクリプタ-指定されたクライアントへのその後の通信のために、失敗したリターン-1

図5は、取得新しいソケット記述子を介して通信します

//接收数据
//成功返回实际接收字节数;失败返回-1,若连接断开则返回0
int recv(int sockfd,char *buf,int len,int flag);

//发送数据
//成功返回实际发送字节数;失败返回-1;连接断开则触发异常
int send(int sockfd,char *data,int len,int flag);

ソケットソケットTCPは、端末上で通信終了するだけでなく、アクティブな情報でなく、情報を記載しているためにrecvので/終了アドレスに移動する必要性によって指定された各プログラムを送信します。
数sockfd:サーバー用のソケット、それを新たに戻り記述子を受け入れる作成されます

図6に示すように、ソケットが閉じられ

int close(int fd);

図7は、クライアントがサーバーへの接続を開始します

int connect(int sockfd,struct sockaddr *srvaddr,socklen_t len);

数sockfd:クライアントソケット-サービスは、ソケット構造体にアドレス情報を終了しますしながら、そうでない場合はバインドされた送信元アドレスを、オペレーティングシステムが自動的に、結合されますで説明
srvaddr:サーバーのアドレス情報

基本的なTCPサーバプログラムの問題

プロセス・サーバーのブロッキング
1を、サーバがクライアント、サイクルおよびコールが受け入れるトランシーバ最初のデータを処理し終えた後、来るこれ以上の接続があるので、流れので、バックアップ、ここで、新しい接続の到着を待っている
2、サーバは、最初のプログラムを受け、クライアントの接続要求、データは、Recv関数は、最初のクライアントの受信を待機してくる。最初のクライアントがデータを送信しない場合は、プログラムの流れは、フォローアップの他の接続のは処理されない場合でも、ここではブロックされます。

プログラムは、新しい接続は、データがいつ来るかわからないがあるだろう時に来ているものを知らないので最終的には、サーバは、プロセスをブロックします、それだけで書かれた最初の接続を取得するためのプログラムの流れを修正することができ、その後、クライアントと(データを受信しますエンド通信)があるが、接続されたクライアントは、おそらくブロックされると通信し得る;
従って結論:サービス側コードは柔軟十分ではないため、サーバ・アプリケーション・プロセスを遮断します。

現在の解決策:マルチストリームソリューションの実装
サーバプログラムは、2つの主要な機能を持っており、目詰まりする可能性があります。各クライアントとの新しい接続/通信を取得し
、実行の主な流れは、新しい接続を取得するための唯一の責任がある場合は、新しい接続を取得した後、クライアントとの通信機能として、実行フローを作成
して新しい実行フローの通信クライアントを作成するために、
新しい接続は、本体のみ実行フローの閉塞を来て、しかし、実行の流れとクライアントが通信は、まだ通信できる
とあればクライアント通信の実現を阻止する、実行の主な流れは、まだ別のクライアントに新しい実行フローの通信を作成し、新しい接続を取得することができます

要約:
サーバは、クライアントの通信を続行することができなかった
主な理由:サーバプロセスが固定され、その過程で様々な機能を実行するために、インターフェイスの各機能は、詰まりやすい
ソリューション:マルチストリームプログラムの実行、各実行フローは、ブロックの実行の流れは、他の実行フローの動作に影響しません、機能のための唯一の責任がある
特定の技術を:マルチプロセス/マルチスレッド化

1、マルチプロセス・タスク
新しい接続の買収は、その後、新しい接続が指定されたクライアントには、この新しい接続の通信に責任があると、子プロセスを作成する場合、親が唯一の新しい接続を取得
(1)、親と子のコードシェアを、そのデータがありますそこに、私たちは新しいソケットを閉じる必要がありますので、しかし、親プロセスは、クライアントと通信しません。サンズの新しいプロセスは、ソケット記述子を持っている
(2)を、親プロセスは回避ゾンビに撮影するので、信号のコールバックプロセスを待っていました

避けゾンビ子プロセス:SIGCHLDシグナルのカスタム処理、親と子それぞれがnewsockを持って、親プロセスが漏れを防止するために速やかにシャットダウンするリソースを使用しない
2を、マルチスレッド処理
メインスレッドはちょうど新しい接続を取得するには、新しい接続を取得した場合、クライアントとのこの新しい接続を介して通信を担当するために、新しいスレッドを作成し
、直接、すべてのデータをコピーすることによって、マルチスレッド、マルチプロセスとは異なり、(1)は、親プロセスがあり、スレッドエントリ機能は、あなたが新しいソケットを渡したいです単語を通信、機能、動作、着信ソケットスレッドエントリ関数を渡す新しいパラメータを形成しなければなりません。
完成されたループがリリースされますので、ローカル変数-時間を渡すパラメータのアドレスは、直接ローカル変数を渡すことはできません
①、ローカル変数に直接適用されませんが、直接アプリケーション・ヒープ・スペースでは、スレッドに最初のアドレス空間をお届けします

TcpSocket *newsock = new TcpSocket();

②は、直接質量参加を通過したディスクリプタの値
(2)、リソースがソケットスレッドが処理されるにもかかわらず、新しいソケットが、唯一のものであることはもちろん、複数のスレッド、手段間で共有されていますしかし、メインスレッドが任意に近い新ソケットは、(スレッドファイルディスクリプタテーブル間で共有)することはできません

公開された59元の記事 ウォン称賛15 ビュー1582

おすすめ

転載: blog.csdn.net/weixin_43867777/article/details/104920377