麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Linux下實(shí)現(xiàn)C語言的http請求實(shí)現(xiàn)

2019-11-11 05:09:25
字體:
供稿:網(wǎng)友

1.     前言

linux下的http請求有許多種方式,其中curl庫是C語言封裝的一個強(qiáng)大的庫,使用curl比封裝socket更加方便。cJSON是一個小型的json封裝庫,可以把數(shù)據(jù)封裝成json格式。本文介紹了這兩種技術(shù),并通過此技術(shù)完成了Linux下的http請求,同時把代碼封裝到quagga下,quagga運(yùn)行時可以正常創(chuàng)建數(shù)據(jù)到ONOS。

2.     Linux下http請求實(shí)現(xiàn)

2.1.    curl簡介

curl命令是一個功能強(qiáng)大的網(wǎng)絡(luò)工具,它能夠通過http、ftp等方式下載文件,也能夠上傳文件。curl命令使用了libcurl庫來實(shí)現(xiàn),libcurl庫常用在C程序中用來處理HTTP請求,curlpp是libcurl的一個C++封裝,這幾個東西可以用在抓取網(wǎng)頁、網(wǎng)絡(luò)監(jiān)控等方面的開發(fā),而curl命令可以幫助來解決開發(fā)過程中遇到的問題。本文檔就是使用curl完成http請求。

2.1.1.    全局初始化

應(yīng)用程序在使用libcurl之前,必須先初始化libcurl。libcurl只需初始化一次。可以使用以下語句進(jìn)行初始化:

curl_global_init();

curl_global_init()接收一個參數(shù),告訴libcurl如何初始化。參數(shù)CURL_GLOBAL_ALL 會使libcurl初始化所有的子模塊和一些默認(rèn)的選項(xiàng),通常這是一個比較好的默認(rèn)參數(shù)值。還有兩個可選值:

CURL_GLOBAL_WIN32

只能應(yīng)用于Windows平臺。它告訴libcurl初始化winsock庫。如果winsock庫沒有正確地初始化,應(yīng)用程序就不能使用socket。在應(yīng)用程序中,只要初始化一次即可。

CURL_GLOBAL_SSL

如果libcurl在編譯時被設(shè)定支持SSL,那么該參數(shù)用于初始化相應(yīng)的SSL庫。同樣,在應(yīng)用程序中,只要初始化一次即可。

libcurl有默認(rèn)的保護(hù)機(jī)制,如果在調(diào)用curl_easy_perform時它檢測到還沒有通過curl_global_init進(jìn)行初始 化,libcurl會根據(jù)當(dāng)前的運(yùn)行時環(huán)境,自動調(diào)用全局初始化函數(shù)。但必須清楚的是,讓系統(tǒng)自已初始化不是一個好的選擇。

當(dāng)應(yīng)用程序不再使用libcurl的時候,應(yīng)該調(diào)用curl_global_cleanup來釋放相關(guān)的資源。在程序中,應(yīng)當(dāng)避免多次調(diào)用curl_global_init和curl_global_cleanup。它們只能被調(diào)用一次。

2.1.2.    easy interface

libcurl中被稱為easy interface的api函數(shù),所有這些函數(shù)都是有相同的前綴:curl_easy 。

要使用easyinterface,首先必須創(chuàng)建一個easy handle,easy handle用于執(zhí)行每次操作。基本上,每個線程都應(yīng)該有自己的easy handle用于數(shù)據(jù)通信(如果需要的話)。千萬不要在多線程之間共享同一個easy handle。下面的函數(shù)用于獲取一個easy handle:

CURL *easy_handle =curl_easy_init();

在easyhandle上可以設(shè)置屬性和操作(action)。easy handle就像一個邏輯連接,用于接下來要進(jìn)行的數(shù)據(jù)傳輸。

使用curl_easy_setopt函數(shù)可以設(shè)置easy handle的屬性和操作,這些屬性和操作控制libcurl如何與遠(yuǎn)程主機(jī)進(jìn)行數(shù)據(jù)通信。一旦在easy handle中設(shè)置了相應(yīng)的屬性和操作,它們將一直作用該easyhandle。也就是說,重復(fù)使用easy hanle向遠(yuǎn)程主機(jī)發(fā)出請求,先前設(shè)置的屬性仍然生效。

easy handle的許多屬性使用字符串(以/0結(jié)尾的字節(jié)數(shù)組)來設(shè)置。通過curl_easy_setopt函數(shù)設(shè)置字符串屬性時,libcurl內(nèi)部會自動拷貝這些字符串,所以在設(shè)置完相關(guān)屬性之后,字符串可以直接被釋放掉(如果需要的話)。

    后面章節(jié)會根據(jù)http的get和post接口對常用的easy handle函數(shù)進(jìn)行說明。

2.2.    cJSON簡介

cJSON是在C語言中解析JSON的開源庫,在cJSON中,一個key-value鍵值對被解析并存放在一個cJSON結(jié)構(gòu)體變量中,其value取值集為:FALSE,TRUE,NULL,NUMBER,STRING,OBJECT,ARRAY。cJOSN庫,僅有兩個文件cJSON.c和cJSON.h。

2.2.1.       cJSON使用說明

下面使用cJSON組裝以下json數(shù)據(jù)

{

    "mac":  "46:E4:3C:A4:11:12",

    "vlan": "-1",

    "ipAddresses":  ["222.222.233.2"],

    "location": {

        "elementId":    "of:0000001e08000fe3",

        "port": "31"

    }

}

代碼如下:

//創(chuàng)建一個object

cJSON *root =cJSON_CreateObject();

    cJSON_AddItemToObject(root,"mac",cJSON_CreateString("46:E4:3C:A4:13:12"));

    cJSON_AddStringToObject(root,"vlan","-1");

    cJSON*array = NULL;

    cJSON_AddItemToObject(root,"ipAddresses",array=cJSON_CreateArray());

    cJSON_AddItemToArray(array,cJSON_CreateString("192.168.10.2"));

    //創(chuàng)建一個子object,將此object添加到root中

    cJSON*location = NULL;

    cJSON_AddItemToObject(root,"location",location=cJSON_CreateObject());

    cJSON_AddStringToObject(location,"elementId","of:0000001e08000fe3");

    cJSON_AddStringToObject(location,"port","31");

    //將json結(jié)構(gòu)格式化到緩沖區(qū)

    char*buf = cJSON_PRint(root);

    //執(zhí)行http請求函數(shù)

http_client_thttp_read_client;

    http_client_read_init(&http_read_client,temp, buf);

    //數(shù)據(jù)使用完之后,把內(nèi)存釋放掉

cJSON_Delete(json);

    free(buf);

2.3.    http的post請求

int http_client_read_init(http_client_t*http_client, const char *url, char *szJsonData)

{

   if (!url) {

        return -1;

    }

    //初始化libcurl,設(shè)置默認(rèn)參數(shù)

   CURLcode return_code = curl_global_init(CURL_GLOBAL_ALL);

   if (CURLE_OK != return_code) {

        printf("initlibcurl failed./n");

       return -1;

    }

    //獲取easy handle

   http_client->handle = curl_easy_init();

   if (!http_client->handle) {

       return -1;

    }

    //通過CURLOPT_URL屬性設(shè)置url

   curl_easy_setopt(http_client->handle, CURLOPT_URL, url);

    //通過CURLOPT_HTTPHEADER定義http消息的header

   struct curl_slist *plist = NULL;

    plist = curl_slist_append(plist,  

                 "Content-Type:application/json"); 

   curl_easy_setopt(http_client->handle, CURLOPT_HTTPHEADER, plist);

    printf("Thejson is: %s/n", szJsonData);

    //通過CURLOPT_POSTFIELDS設(shè)置要POST的數(shù)據(jù)

curl_easy_setopt(http_client->handle,CURLOPT_POSTFIELDS, szJsonData);

    //通過CURLOPT_USERPWD屬性來設(shè)置用戶名與密碼。參數(shù)是”user:passWord “的字符串

    curl_easy_setopt(http_client->handle,CURLOPT_USERPWD, "karaf:karaf");

    //使用curl_easy_perform執(zhí)行上傳數(shù)據(jù)

    curl_easy_perform(http_client->handle);

    //任務(wù)執(zhí)行結(jié)束使用curl_easy_cleanup把內(nèi)存釋放

curl_easy_cleanup(http_client->handle);

return 0;

}

2.4.    http的get請求

int http_client_init(http_client_t*http_client, const char *url, write_cb_t *write_data, void *userp)

{

   if (!url) {

       return -1;

    }

    //初始化libcurl,設(shè)置默認(rèn)參數(shù)

   CURLcode return_code;

    return_code= curl_global_init(CURL_GLOBAL_ALL);

   if (CURLE_OK != return_code) {

        printf("initlibcurl failed./n");

       return -1;

    }

    //獲取easy handle

   http_client->handle = curl_easy_init();

   if (!http_client->handle) {

       return -1;

}

    //通過CURLOPT_URL屬性設(shè)置url

curl_easy_setopt(http_client->handle,CURLOPT_URL, url);

//注冊回調(diào)函數(shù)write_cb,回調(diào)函數(shù)將會在接收到數(shù)據(jù)的時候被調(diào)用

   curl_easy_setopt(http_client->handle, CURLOPT_WRITEFUNCTION, write_data);     //通過CURLOPT_USERPWD屬性來設(shè)置用戶名與密碼。參數(shù)是”user:password “的字符串

    curl_easy_setopt(http_client->handle,CURLOPT_USERPWD, "karaf:karaf");

if (userp) {

//設(shè)置寫數(shù)據(jù)的變量

       curl_easy_setopt(http_client->handle, CURLOPT_WRITEDATA, userp);

}

//使用curl_easy_perform執(zhí)行上傳數(shù)據(jù)

    curl_easy_perform(http_client->handle);

    //任務(wù)執(zhí)行結(jié)束使用curl_easy_cleanup把內(nèi)存釋放

curl_easy_cleanup(http_client->handle);

   return 0;

}

//回調(diào)函數(shù),將接收到的數(shù)據(jù)保存到本地文件中,同時顯示在控制臺上。

static size_t write_data(void *buf, size_tsize, size_t nmemb, void *userp)

{

   FILE *fp = (FILE *)userp;

   size_t return_size = fwrite(buf, size, nmemb, fp);

   printf("write_data: %ld, return_size: %ld/n", nmemb,return_size);

   return return_size;

}

2.5.    http的del請求

//獲取easy handle

   http_client->handle = http_client_init();

   if (!http_client->handle) {

       return -1;

    }

    // 通過CURLOPT_URL屬性設(shè)置url

   curl_easy_setopt(http_client->handle, CURLOPT_URL, url);

    // 設(shè)置http發(fā)送的內(nèi)容類型為JSON 

   struct curl_slist *plist = NULL;

    //plist = curl_slist_append(plist,

        //"Content-Type:application/json");

    curl_easy_setopt(http_client->handle,CURLOPT_HTTPHEADER, plist);

    // 設(shè)置要POST的JSON數(shù)據(jù) 

   //curl_easy_setopt(http_client->handle, CURLOPT_POSTFIELDS,szJsonData);

    curl_easy_setopt(http_client->handle,CURLOPT_CUSTOMREQUEST, "DELETE");

    curl_easy_setopt(http_client->handle,CURLOPT_USERPWD, "karaf:karaf");

2.6.    編譯并執(zhí)行

代碼完成之后,使用gcc運(yùn)行時需要帶如下參數(shù):

gcc -o http_client http_client.ccJSON.c -lcurl –lm

編譯之后開始運(yùn)行

./http_client

通過抓包可以看到http報文

 

注意事項(xiàng):

1.  -lcurl是鏈接curl庫,如果運(yùn)行報如下錯誤:

mlogc.c:32:23: error: curl/curl.h: No such fileor directory

mlogc.c:1091: error: expected ‘)’ before ‘*’token

mlogc.c: In function ‘logc_init’:

 則需要安裝如下依賴包:libcurl-dev, libcurl-devel

 centOS上安裝依賴包:

yum install libcurl-dev libcurl-devel  

2.   –lm是鏈接math的庫,由于cJSON需要調(diào)用math庫,如果不添加會報如下錯誤:

3.   如果有多個方法例如:get/post/delete等用到的URL一樣,需要把如下代碼,包含URL的頭部注釋掉,否則報文發(fā)布出去。

    // 設(shè)置http發(fā)送的內(nèi)容類型為JSON 

   struct curl_slist *plist = NULL;

    //plist = curl_slist_append(plist,

        //"Content-Type:application/json");

    curl_easy_setopt(http_client->handle,CURLOPT_HTTPHEADER, plist);


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 日本高清在线免费 | 91精品国产91热久久久做人人 | 国产成人午夜高潮毛片 | 在线播放免费视频 | 九九综合视频 | 91国在线高清视频 | 最近日本电影hd免费观看 | 国产免费区| 久久久www成人免费精品 | av在线看网站 | 看毛片的网址 | 黄色网址在线免费播放 | 日本在线播放一区 | 本色视频aaaaaa一级网站 | 国产精品999在线 | 日日爱夜夜操 | 久久久久久久久久久久久久久伊免 | 国产精品久久久久久影视 | 色戒在线版 | 在线看一区二区三区 | 久久久青 | 福利在线小视频 | 亚洲黑人在线观看 | 9999久久| 欧美日韩在线视频一区 | 羞羞视频2023 | 在线观看免费毛片视频 | 欧美 videos粗暴 | 国产精品.com | 久久区二区 | 久久毛片免费观看 | 在线观看免费污视频 | 欧美成人精品一区 | 久久精品视频12 | 久久精品资源 | 久久我不卡 | 一级国产航空美女毛片内谢 | 日韩视频一区二区三区在线观看 | 成人毛片100免费观看 | 成人性视频免费网站下载软件 | 一级免费看片 |