通過C++編程發(fā)起HTTP請求

前些天完成一個小項目蒲讯,其主要功能是通過C++編程發(fā)起http請求劫映,并對通訊信息加密。其中難點在于對方是java服務(wù)器嗤攻,交換數(shù)據(jù)信息需要嚴格按照某種數(shù)據(jù)交換格式如json,xml等來定義诽俯。期間使用了一個第三方庫ghttp妇菱,下面我們主要來分析ghttp源碼來了解整個http請求的過程。

第一步:解析域名通過域名獲取對應(yīng)請求的主機或服務(wù)器的ip和端口暴区。
第二步:通過socket編程向上述主機或服務(wù)器的ip和端口建立連接闯团。
第三步:把請求內(nèi)容按照http協(xié)議來進行組裝
第四步:將封裝好的http協(xié)議內(nèi)容發(fā)送到目的服務(wù)器
第五步:接收服務(wù)器反饋內(nèi)容

htpp協(xié)議與鏈接地址的全部內(nèi)容_ghttp_request結(jié)構(gòu)體
<pre>
<code>struct _ghttp_request</code>
{
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;
};
</pre>

*** 1.在ghttp中與建立連接相關(guān)的數(shù)據(jù)結(jié)構(gòu)和函數(shù)定義 ***
1.1 http_uri是對請求URL對象的解析
<pre>
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;
</pre>
1.2 http_trans_conn是對信息發(fā)送對象的封裝
<pre>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;
</pre>

通過對URL的解析將必要的連接目標信息裝入http_uri對象。然后從http_uri對象中取出host和port保存到http_trans_conn對象颜启。http_trans_conn不僅保存目的服務(wù)器的IP與端口信息還定義了發(fā)送和接收緩存以及同步異步方式偷俭。

1.3 信息交換的三大函數(shù)
<pre>int http_trans_connect(http_trans_conn *a_conn)</pre>
通過向http_trans_conn指定的host和port發(fā)起連接,其中使用gethostbyname(a_conn->host)來獲取指定主機的真實ip地址。通過socket方式建立連接。

<pre>int http_req_send(a_request->req, a_request->conn)
</pre>
向連接的目的地發(fā)送數(shù)據(jù)泵三,實現(xiàn)函數(shù)write();

<pre>
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)
</pre>
*從連接通道中讀取數(shù)據(jù),實現(xiàn)函數(shù)read();

*** 2 在ghttp中對http協(xié)議的封裝 ***

2.1 請求報文
<pre>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;
</pre>
下面以post方法為例加上一個標準的請求報文來分析這個結(jié)構(gòu)體负溪。該請求報文的請求方法為post保存在http_req_type type類型的type里。協(xié)議版本號HTTP/1.1保存在http_ver里济炎。/search保存在resource屬性里面川抡。
<pre>POST /search HTTP/1.1</pre>

host保存到char *host屬性中。
<pre>
Host: <a >www.google.cn</a>
</pre>
下面此段都為頭部屬性以鍵值對列的形式存儲在
http_hdr_list *headers中须尚。
<pre>
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: <a >http://www.google.cn/</a>
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
</pre>
在發(fā)送前http_req結(jié)構(gòu)體中報文的各種信息按照http協(xié)議標準格式定義來封裝崖堤,存入http_trans_conn結(jié)構(gòu)體中的io_buf中。然后通過write方法發(fā)送耐床。

2.2 響應(yīng)報文

通過read函數(shù)讀取接收到的數(shù)據(jù)保存到http_trans_conn中的io_buf中并由io_buf_alloc指定其在io_buf中的位置密幔。然后通過
<pre>
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)
</pre>
倆函數(shù)來將io_buf中的內(nèi)容解析到http_resp結(jié)構(gòu)體中。
<pre>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;
</pre>
通過本文撩轰,我們可以看到協(xié)議即語境胯甩,不管你是哪國人,中國人堪嫂,美國人或者日本人偎箫,只要你使用相同的語境(英語或者其他語言)交流大家都能實現(xiàn)基本的溝通。不同平臺也是不管你是C++實現(xiàn)或者java皆串,只要嚴格按照遵守http協(xié)議規(guī)定都能實現(xiàn)有效的信息交換淹办。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市恶复,隨后出現(xiàn)的幾起案子怜森,更是在濱河造成了極大的恐慌齐遵,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件塔插,死亡現(xiàn)場離奇詭異,居然都是意外死亡拓哟,警方通過查閱死者的電腦和手機想许,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來断序,“玉大人流纹,你說我怎么就攤上這事∥ナ” “怎么了漱凝?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長诸迟。 經(jīng)常有香客問我茸炒,道長,這世上最難降的妖魔是什么阵苇? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任壁公,我火速辦了婚禮,結(jié)果婚禮上绅项,老公的妹妹穿的比我還像新娘紊册。我一直安慰自己,他們只是感情好快耿,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布囊陡。 她就那樣靜靜地躺著,像睡著了一般掀亥。 火紅的嫁衣襯著肌膚如雪撞反。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天铺浇,我揣著相機與錄音痢畜,去河邊找鬼。 笑死鳍侣,一個胖子當著我的面吹牛丁稀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播倚聚,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼线衫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了惑折?” 一聲冷哼從身側(cè)響起授账,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤枯跑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后白热,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體敛助,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年屋确,在試婚紗的時候發(fā)現(xiàn)自己被綠了纳击。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡攻臀,死狀恐怖焕数,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情刨啸,我是刑警寧澤堡赔,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站设联,受9級特大地震影響善已,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜离例,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一雕拼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧粘招,春花似錦啥寇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至袍冷,卻和暖如春磷醋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背胡诗。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工邓线, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人煌恢。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓骇陈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親瑰抵。 傳聞我的和親對象是個殘疾皇子你雌,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)二汛,斷路器婿崭,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • 第一章 Nginx簡介 Nginx是什么 沒有聽過Nginx拨拓?那么一定聽過它的“同行”Apache吧!Ngi...
    JokerW閱讀 32,672評論 24 1,002
  • https://nodejs.org/api/documentation.html 工具模塊 Assert 測試 ...
    KeKeMars閱讀 6,331評論 0 6
  • 一氓栈、概念(載錄于:http://www.cnblogs.com/EricaMIN1987_IT/p/3837436...
    yuantao123434閱讀 8,353評論 6 152
  • Http協(xié)議詳解 標簽(空格分隔): Linux 聲明:本片文章非原創(chuàng)渣磷,內(nèi)容來源于博客園作者MIN飛翔的HTTP協(xié)...
    Sivin閱讀 5,223評論 3 82