C++プログラミングによるHTTPリクエストの開始

5437 ワード

先日、C++プログラミングでhttpリクエストを開始し、通信情報を暗号化する小さなプロジェクトが完成しました.難点は相手がjavaサーバであり,データ情報を交換するにはjson,xmlなどのデータ交換フォーマットに厳格に従って定義する必要があることである.期間中にサードパーティ製ライブラリghtpが使用され、主にghtpソースコードを分析してhttpリクエスト全体のプロセスを理解します.
ステップ1:ドメイン名を解析し、ドメイン名を使用して対応するリクエストのホストまたはサーバのipとポートを取得します.
ステップ2:socketプログラミングにより、上記のホストまたはサーバのipとポートに接続を確立します.
ステップ3:リクエスト内容をhttpプロトコルに従って組み立てる
ステップ4:カプセル化されたhttpプロトコルの内容を宛先サーバに送信
ステップ5:サーバからのフィードバックの受信
httpプロトコルとリンクアドレスのすべての内容_ghttp_request構造体

struct _ghttp_request
{
http_uri *uri;

http_uri *proxy;

http_req *req;

http_resp *resp;
http_trans_conn *conn;
const char *errstr;
int connected;
ghttp_proc proc;
char *username;
char *password;
char *authtoken;
char *proxy_username;
char *proxy_password;
char *proxy_authtoken;
};

*** 1.ghtpにおける接続の確立に関するデータ構造と関数定義***1.1 http_uriは、要求URLオブジェクトに対する解析

typedef struct http_uri_tag
{
char full; / full URL */
char proto; / protocol */
char host; / copy semantics */
unsigned short port;
char resource; / copy semantics */
} http_uri;
.1.2 http_trans_connは、情報送信対象のパッケージ
typedef struct http_trans_conn_tag {
struct hostent *hostinfo;
struct sockaddr_in saddr;
char *host;
char proxy_host;
int sock;
short port;
short proxy_port;
http_trans_err_type error_type;
int error;
int sync; /
sync or async? */
char io_buf; / buffer /
int io_buf_len; /
how big is it? /
int io_buf_alloc; /
how much is used /
int io_buf_io_done; /
how much have we already moved? /
int io_buf_io_left; /
how much data do we have left? /
int io_buf_chunksize; /
how big should the chunks be that get
read in and out be? /
int last_read; /
the size of the last read /
int chunk_len; /
length of a chunk. */
char errstr; / a hint as to an error */
} http_trans_conn;
である
URLの解析で必要な接続先情報をhttp_に読み込むuriオブジェクト.そしてhttp_uriオブジェクトからhostとportを取り出してhttp_に保存trans_connオブジェクト.http_trans_connは,宛先サーバのIPとポート情報を保存するだけでなく,キャッシュの送信と受信,同期非同期方式も定義する.
1.3情報交換の三大関数
int http_trans_connect(http_trans_conn *a_conn)
http_trans_connが指定したhostとportは接続を開始し、gethostbyname(a_conn->host)を使用して指定したホストの実際のipアドレスを取得します.ソケット方式で接続を確立します.
int http_req_send(a_request->req, a_request->conn)
接続先にデータを送信し、関数write()を実現する.

int http_resp_read_headers(a_request->resp, a_request->conn)
int http_resp_read_body(a_request->resp,a_request->req,a_request->conn)
*接続チャネルからデータを読み出し、関数read()を実現する.
***2 httpでのhttpプロトコルのカプセル化***
2.1要求メッセージ
typedef struct http_req_tag {
http_req_type type;
float http_ver;
char *host;
char *full_uri;
char *resource;
char *body;
int body_len;
http_hdr_list *headers;
http_req_state state;
} http_req;
は、次にpostメソッドを例に、この構造体を分析するために標準的な要求メッセージを追加する.このリクエストメッセージのリクエスト方法はpostをhttp_に保存するreq_type typeタイプのtypeにあります.プロトコルバージョン番号HTTP/1.1 http_に保存ver里./searchはresourceプロパティに保存されます.
POST /search HTTP/1.1

hostはchar*hostプロパティに保存されます.

Host: www.google.cn
次のセグメントは、ヘッダ属性がキー値対列としてhttp_に格納されます.hdr_List*headersにあります.

Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint,
application/msword, application/x-silverlight, application/x-shockwave-flash, /
Referer: http://www.google.cn/
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld)
Connection: Keep-Alive
Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g;
NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMf
O2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y-
FxlRugatx63JLv7CWMD6UB_O_r
送信前http_req構造体におけるメッセージの各種情報はhttpプロトコル標準フォーマット定義に従ってカプセル化され、http_に格納されるtrans_conn構造体のio_bufにあります.そしてwriteメソッドで送信します.
2.2応答メッセージ
read関数で受信したデータを読み込みhttp_に保存trans_connのio_bufでio_buf_allocはio_で指定しますbufの位置.その後、

int http_resp_read_headers(http_resp *a_resp, http_trans_conn *a_conn)
int http_resp_read_body(http_resp *a_resp,http_req *a_req,http_trans_conn *a_conn)
の2つの関数によってio_bufの内容をhttp_に解析resp構造体.
typedef struct http_resp_tag
{
float http_ver;
int status_code;
char *reason_phrase;
http_hdr_list *headers;
char *body;
int body_len;
int content_length;
int flushed_length;
http_resp_header_state header_state;
http_resp_body_state body_state;
} http_resp;
本文を通じて、私たちは合意すなわち文脈を見ることができて、あなたがどの国の人であろうと、中国人であろうと、アメリカ人であろうと、日本人であろうと、あなたが同じ文脈(英語あるいはその他の言語)を使って交流すれば、みんなは基本的なコミュニケーションを実現することができます.異なるプラットフォームも、C++実装やjavaにかかわらず、httpプロトコルの規定を厳格に遵守すれば、有効な情報交換を実現することができます.