TeamTalkクライアントソース分析5


TeamTalkクライアントソース分析5
  • 一,socketパッケージ
  • 1,StreamingSocket
  • 2,ProxySocket
  • 2,HttpRequest
  • 三,HttpResponse
  • 四,HttpClient
  • 五、具体的な機能業務例
  • 前章ではスレッドプールの概念と基本的な使用を紹介したが,最後の例ではDownloadAvatarHttpOperation::processOpertion()関数ではHttp::HttpRequestを用いてhttpリクエストを実現し,非常に便利であり,TeamTalkではこれらのhttp操作はすべてオリジナルのSocketを用いてhttpclientエンジニアリングでカプセル化して実現されている.現在、多くの一般的なサードパーティのネットワークライブラリが使用されていますが、httpプロトコルのパッケージ、発注、リターンの具体的な実現を学ぶのに役立ちます.
    一、socketパッケージ
    httpclientエンジニアリングのsocketフィルタには、StreamingSocketがオリジナルのsocketをカプセル化し、ProxySocketがエージェントをサポートするsocketをカプセル化するなど、オリジナルのsocket操作をカプセル化するクラスファイルが含まれています.socket_helperにはsocket,connect,recvなどの関数のパッケージがあります.StreamingSocket呼び出し用です.
    1,StreamingSocket
    socket通信の基本手順:socketを初期化し、ipとポートをバインドし、要求を送信し、リスニングをループし、Streamingsocketではこれらの操作を二次パッケージ化します.TeamTalk客户端源码分析五_第1张图片そのうち_handleメンバー変数はSOCKETオブジェクト(SOCKETはint,typedef int SOCKET)であり、Streamingsocketでは主に2つのことを行う:1)転送されたipとパンツを保存する;2)呼び出しソケット_helper.hファイルの関数で操作_handle. 接続を例にとると、Streamingsocket::connect関数にipとportを保存し、SocketHelper::connectSocketを呼び出します.TeamTalk客户端源码分析五_第2张图片SocketHelper::connectSocketでは、実際にAPI関数::socketおよび::connectを呼び出してネットワーク接続を確立します.TeamTalk客户端源码分析五_第3张图片Streamingsocketの他の関数も同じ原理で、最終的にはsocket_を呼び出します.helper.hにおけるインタフェースは実現される.
    2,ProxySocket
    これはエージェントをサポートするsocketパッケージクラスで、内部の原理はStreamingsocketと同じですが、エージェントを使用しているため、ネットワーク接続を行う際にStreamingsocketとは異なり、エージェントのipとポートを使用してネットワーク要求を送信する必要があります(エージェントはHTTPエージェント、SOCKET 4エージェント、SOCKET 5エージェントに分けられ、具体的な違いは自分で資料を検索することができます)、異なるエージェントタイプによって、connectの時に異なる処理をします.TeamTalk客户端源码分析五_第4张图片HTTPエージェントとSOCKET 5エージェントは、アイデンティティ認証が必要なので、ネットワーク接続後、アイデンティティ認証要求を1回発行する必要があります.エージェントの具体的な実装については,コードを自分で見ることができ,よく理解できる.
    二、HttpRequest
    HttpRequestクラスは主にhttpリクエストに関するパラメータを格納し,リクエスト方式(GET/POST),リクエストヘッダ,リクエストurlなどの情報を含む.HttpRequestの最も重要なインタフェースはsetRequestで、httpリクエスト方式とurlを渡して、そしてurl解析に対してホスト名、ドメイン名、およびポート番号を得て、具体的な解析方式はURLParser類の中でカプセル化して、主に文字列の解析操作で、ここで多すぎる描写をしないで、みんなは直接コードを見ることができます.TeamTalk客户端源码分析五_第5张图片HttpRequestには、void addField(const std::string&name,const std::string&value)HTTPボディパラメータvoid saveToFile(const std::wstring&filepath)設定ファイルのダウンロードパスvoid setBody(const std::string&body)設定HTTPパッケージコンテンツvoid addHeaderField(const std::string&name,const std::string&value);HTTPヘッダフィールドを設定すると、つまり、HttpRequestは1つのストレージクラスにすぎず、HTTPリクエストに関連する任意のパラメータを格納する.
    三、HttpResponse
    HttpResponseクラスもデータストレージクラスであり、主にhttpリクエストのデータを保存し、getインタフェースを提供して外部呼び出しにデータを取得する.TeamTalk客户端源码分析五_第6张图片
    四、HttpClient
    HttpClientは具体的な操作クラスであり、最も主要で最もよく使われるインタフェースはbool execute(HttpRequest*request,HttpResponse*respone)である.HttpRequestオブジェクトをリクエスト送信し、結果をHttpResponseに格納します.TeamTalk客户端源码分析五_第7张图片execute関数では、まずProxySocketクラスを呼び出してネットワーク接続の確立を行い(ProxySocketのデフォルトはエージェントを使用せず、StreamingSocketに相当)、httpがgetかpostかに基づいてhttpGetまたはhttpPostを呼び出してリクエストを送信します.GETとPOSTの最大の違いは、GETリクエストが1つのHTTPヘッダのみを送信することであり、POSTリクエストはHTTPヘッダ(ヘッダにもfiledsが追加される)を送信するほか、Bodyを送信する必要があることである.TeamTalk客户端源码分析五_第8张图片sendHeaderでは、httpヘッダ情報をHttpRequestオブジェクトで取得する
    int		HttpRequest::generateHeader(std::string& header)
    {
    	header.clear();
    
    	//       
    	header.append(_http_method+" ");
    	header.append(_object);
    	header.append(" HTTP/1.1\r
    "); // header.append("Host:"); header.append(_http_host); //add by kuaidao host header.append(":"); header.append(Util::num_to_string(_port_number)); header.append("\r
    "); // Body , ContentLength if (_stricmp(_http_method.c_str(),kpost) == 0) { calcBody(); } // Header Field size_t field_size = _header_fields.size(); for (size_t i = 0; i < field_size; i ++) { std::string& name = _header_fields[i]._field_name; std::string& value = _header_fields[i]._field_value; header.append(name + ": " + value + "\r
    "); } // \r
    header.append("\r
    "); /// return (int)header.size(); }

    次にProxySocket::writeAll(const char*source_buffer,int max_write_length)を呼び出してヘッダ情報を送信する.POSTリクエストであれば、HTTPパケットを送信する必要もあり、まずhttpパケット情報を取得するためにHttpRequestオブジェクトでもあり、次にProxySocket::writeAll(const char*source_buffer,int max_write_length)でパケット情報を送信する.パッケージの充填は、HttpRequest::generateHeader(std::string&header)で呼び出されます.具体的には、HttpRequest::calcBody()関数に実装されます.
    五、具体的な機能業務例
    主なパッケージクラスと実装関数はここまで紹介されていますが、具体的な詳細はコードを研究する必要があるに違いありません.最後に、ユーザーのアイコンダウンロードという機能業務を例に、プロセス全体をつなぎ合わせました.DownloadAvatarHttpOperation::processOpertion()には、1つのHttpClientが1つのHttpRequestに対応し、1つのHttpRequestが1つのsocketに対応するため、ポインタで繰り返し使用しないでください.HttpRequestのコンストラクション関数にhttpリクエストタイプ「GET」とリクエストurl(コンストラクション関数でurlの解析が完了し、ip、ポート、ドメイン名に関する情報が取得された)が入力され、saveToFile設定ファイルダウンロードパスが呼び出されます.最後に、HttpClient::executeを実行します.TeamTalk客户端源码分析五_第9张图片HttpClient::execute関数では、リモートipとのネットワーク接続を完了するためにsocketパッケージクラスProxySocketを呼び出し、HTTPパッケージヘッダとパッケージ情報を送信します.その後、HttpClient::getResponse()でProxySocket::readによってパケット情報を直接読み出し、私たちが取り戻したデータはパケットヘッダとパケットボディの混合データなので、それらを解析する必要があります.最終的な解析結果は、HttpResponseに埋め込まれます.TeamTalk客户端源码分析五_第10张图片もちろん中にはファイルダウンロード操作も含まれており、HttpResponseReceiverクラスを使用しており、中で読み取ったデータはUtil::FileWriterを通じてファイルに書き込まれている.これらの操作は、UIスレッド以外の作業スレッドで処理されるため、インタフェースプログラムに影響を与えないため、同期されます.
    自分のプロジェクトでサードパーティ製ライブラリを使いたくない場合は、このプロジェクトを直接移植することができ、インタフェースが簡単で、使いやすいです.