TeamTalkクライアントソース分析5
8124 ワード
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ではこれらの操作を二次パッケージ化します.そのうち_handleメンバー変数はSOCKETオブジェクト(SOCKETはint,typedef int SOCKET)であり、Streamingsocketでは主に2つのことを行う:1)転送されたipとパンツを保存する;2)呼び出しソケット_helper.hファイルの関数で操作_handle. 接続を例にとると、Streamingsocket::connect関数にipとportを保存し、SocketHelper::connectSocketを呼び出します.SocketHelper::connectSocketでは、実際にAPI関数::socketおよび::connectを呼び出してネットワーク接続を確立します.Streamingsocketの他の関数も同じ原理で、最終的にはsocket_を呼び出します.helper.hにおけるインタフェースは実現される.
2,ProxySocket
これはエージェントをサポートするsocketパッケージクラスで、内部の原理はStreamingsocketと同じですが、エージェントを使用しているため、ネットワーク接続を行う際にStreamingsocketとは異なり、エージェントのipとポートを使用してネットワーク要求を送信する必要があります(エージェントはHTTPエージェント、SOCKET 4エージェント、SOCKET 5エージェントに分けられ、具体的な違いは自分で資料を検索することができます)、異なるエージェントタイプによって、connectの時に異なる処理をします.HTTPエージェントとSOCKET 5エージェントは、アイデンティティ認証が必要なので、ネットワーク接続後、アイデンティティ認証要求を1回発行する必要があります.エージェントの具体的な実装については,コードを自分で見ることができ,よく理解できる.
二、HttpRequest
HttpRequestクラスは主にhttpリクエストに関するパラメータを格納し,リクエスト方式(GET/POST),リクエストヘッダ,リクエストurlなどの情報を含む.HttpRequestの最も重要なインタフェースはsetRequestで、httpリクエスト方式とurlを渡して、そしてurl解析に対してホスト名、ドメイン名、およびポート番号を得て、具体的な解析方式はURLParser類の中でカプセル化して、主に文字列の解析操作で、ここで多すぎる描写をしないで、みんなは直接コードを見ることができます.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インタフェースを提供して外部呼び出しにデータを取得する.
四、HttpClient
HttpClientは具体的な操作クラスであり、最も主要で最もよく使われるインタフェースはbool execute(HttpRequest*request,HttpResponse*respone)である.HttpRequestオブジェクトをリクエスト送信し、結果をHttpResponseに格納します.execute関数では、まずProxySocketクラスを呼び出してネットワーク接続の確立を行い(ProxySocketのデフォルトはエージェントを使用せず、StreamingSocketに相当)、httpがgetかpostかに基づいてhttpGetまたはhttpPostを呼び出してリクエストを送信します.GETとPOSTの最大の違いは、GETリクエストが1つのHTTPヘッダのみを送信することであり、POSTリクエストはHTTPヘッダ(ヘッダにもfiledsが追加される)を送信するほか、Bodyを送信する必要があることである.sendHeaderでは、httpヘッダ情報をHttpRequestオブジェクトで取得する
次に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を実行します.HttpClient::execute関数では、リモートipとのネットワーク接続を完了するためにsocketパッケージクラスProxySocketを呼び出し、HTTPパッケージヘッダとパッケージ情報を送信します.その後、HttpClient::getResponse()でProxySocket::readによってパケット情報を直接読み出し、私たちが取り戻したデータはパケットヘッダとパケットボディの混合データなので、それらを解析する必要があります.最終的な解析結果は、HttpResponseに埋め込まれます.もちろん中にはファイルダウンロード操作も含まれており、HttpResponseReceiverクラスを使用しており、中で読み取ったデータはUtil::FileWriterを通じてファイルに書き込まれている.これらの操作は、UIスレッド以外の作業スレッドで処理されるため、インタフェースプログラムに影響を与えないため、同期されます.
自分のプロジェクトでサードパーティ製ライブラリを使いたくない場合は、このプロジェクトを直接移植することができ、インタフェースが簡単で、使いやすいです.
一、socketパッケージ
httpclientエンジニアリングのsocketフィルタには、StreamingSocketがオリジナルのsocketをカプセル化し、ProxySocketがエージェントをサポートするsocketをカプセル化するなど、オリジナルのsocket操作をカプセル化するクラスファイルが含まれています.socket_helperにはsocket,connect,recvなどの関数のパッケージがあります.StreamingSocket呼び出し用です.
1,StreamingSocket
socket通信の基本手順:socketを初期化し、ipとポートをバインドし、要求を送信し、リスニングをループし、Streamingsocketではこれらの操作を二次パッケージ化します.そのうち_handleメンバー変数はSOCKETオブジェクト(SOCKETはint,typedef int SOCKET)であり、Streamingsocketでは主に2つのことを行う:1)転送されたipとパンツを保存する;2)呼び出しソケット_helper.hファイルの関数で操作_handle. 接続を例にとると、Streamingsocket::connect関数にipとportを保存し、SocketHelper::connectSocketを呼び出します.SocketHelper::connectSocketでは、実際にAPI関数::socketおよび::connectを呼び出してネットワーク接続を確立します.Streamingsocketの他の関数も同じ原理で、最終的にはsocket_を呼び出します.helper.hにおけるインタフェースは実現される.
2,ProxySocket
これはエージェントをサポートするsocketパッケージクラスで、内部の原理はStreamingsocketと同じですが、エージェントを使用しているため、ネットワーク接続を行う際にStreamingsocketとは異なり、エージェントのipとポートを使用してネットワーク要求を送信する必要があります(エージェントはHTTPエージェント、SOCKET 4エージェント、SOCKET 5エージェントに分けられ、具体的な違いは自分で資料を検索することができます)、異なるエージェントタイプによって、connectの時に異なる処理をします.HTTPエージェントとSOCKET 5エージェントは、アイデンティティ認証が必要なので、ネットワーク接続後、アイデンティティ認証要求を1回発行する必要があります.エージェントの具体的な実装については,コードを自分で見ることができ,よく理解できる.
二、HttpRequest
HttpRequestクラスは主にhttpリクエストに関するパラメータを格納し,リクエスト方式(GET/POST),リクエストヘッダ,リクエストurlなどの情報を含む.HttpRequestの最も重要なインタフェースはsetRequestで、httpリクエスト方式とurlを渡して、そしてurl解析に対してホスト名、ドメイン名、およびポート番号を得て、具体的な解析方式はURLParser類の中でカプセル化して、主に文字列の解析操作で、ここで多すぎる描写をしないで、みんなは直接コードを見ることができます.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インタフェースを提供して外部呼び出しにデータを取得する.
四、HttpClient
HttpClientは具体的な操作クラスであり、最も主要で最もよく使われるインタフェースはbool execute(HttpRequest*request,HttpResponse*respone)である.HttpRequestオブジェクトをリクエスト送信し、結果をHttpResponseに格納します.execute関数では、まずProxySocketクラスを呼び出してネットワーク接続の確立を行い(ProxySocketのデフォルトはエージェントを使用せず、StreamingSocketに相当)、httpがgetかpostかに基づいてhttpGetまたはhttpPostを呼び出してリクエストを送信します.GETとPOSTの最大の違いは、GETリクエストが1つのHTTPヘッダのみを送信することであり、POSTリクエストはHTTPヘッダ(ヘッダにもfiledsが追加される)を送信するほか、Bodyを送信する必要があることである.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を実行します.HttpClient::execute関数では、リモートipとのネットワーク接続を完了するためにsocketパッケージクラスProxySocketを呼び出し、HTTPパッケージヘッダとパッケージ情報を送信します.その後、HttpClient::getResponse()でProxySocket::readによってパケット情報を直接読み出し、私たちが取り戻したデータはパケットヘッダとパケットボディの混合データなので、それらを解析する必要があります.最終的な解析結果は、HttpResponseに埋め込まれます.もちろん中にはファイルダウンロード操作も含まれており、HttpResponseReceiverクラスを使用しており、中で読み取ったデータはUtil::FileWriterを通じてファイルに書き込まれている.これらの操作は、UIスレッド以外の作業スレッドで処理されるため、インタフェースプログラムに影響を与えないため、同期されます.
自分のプロジェクトでサードパーティ製ライブラリを使いたくない場合は、このプロジェクトを直接移植することができ、インタフェースが簡単で、使いやすいです.