<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://jackxiang.com/post//</link>
<title><![CDATA[[实践OK]C语言 HTTP上传文件-利用libcurl库上传文件, curl连接超时的问题 特别是获取返回头及内容的c写法。]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Fri, 14 Nov 2014 06:09:56 +0000</pubDate> 
<guid>http://jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	curl是Linux下一个非常著名的下载库，通过这个库，可以很简单的实现文件的下载等操作。<br/>一、看一个简单的例子（学习其用static字符串数组和指针的返回判断这块值得学习并记住）：<br/><textarea name="code" class="php" rows="15" cols="100">
#include &lt;curl/curl.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

CURL *curl;
CURLcode res;

size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;if (strlen((char *)stream) + strlen((char *)ptr) &gt; 999999) return 0;
&nbsp;&nbsp;&nbsp;&nbsp;strcat(stream, (char *)ptr);
&nbsp;&nbsp;&nbsp;&nbsp;return size*nmemb;
&#125;

char *down_file(char *filename)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;static char str[10000000];
&nbsp;&nbsp;&nbsp;&nbsp;strcpy(str,&quot;&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;//return “”;

&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_URL, filename); //设置下载地址

&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);//设置超时时间

&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);//设置写数据的函数

&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_WRITEDATA, str);//设置写数据的变量

&nbsp;&nbsp;&nbsp;&nbsp;res = curl_easy_perform(curl);//执行下载

&nbsp;&nbsp;&nbsp;&nbsp;str[9999999] = &#039;&#92;0&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;if(CURLE_OK != res) return NULL;//判断是否下载成功

&nbsp;&nbsp;&nbsp;&nbsp;return str;
&#125;

int main()
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;char url[200];
&nbsp;&nbsp;&nbsp;&nbsp;curl = curl_easy_init();//对curl进行初始化

&nbsp;&nbsp;&nbsp;&nbsp;char *result;
&nbsp;&nbsp;&nbsp;&nbsp;while(fgets(url, 200, stdin))&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = down_file(url);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (result) puts(result);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else puts(&quot;Get Error!&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;&#92;nPlease Input a url:&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_cleanup(curl);//释放curl资源


&nbsp;&nbsp;&nbsp;&nbsp;return 0;
&#125;
</textarea><br/><br/>二、分为header和包体数据两个回调指针：<br/><textarea name="code" class="php" rows="15" cols="100">
#if 1
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, pc_method);

#if (CURL_HEADER == 0)
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_HEADER, 1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //下载数据包括HTTP头部, The default value for this parameter is 0.
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_get_head); //下载数据的回调函数
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_WRITEDATA, pc_ret);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//下载数据的指针

#else
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, callback_get_head); //头部数据的回调函数
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_HEADERDATA, pc_ret);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//头部数据的指针
#endif

&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_headers);&nbsp;&nbsp;&nbsp;&nbsp;//多行的HTTP头部
#endif
</textarea><br/><br/><textarea name="code" class="php" rows="15" cols="100">
size_t callback_get_head(void *ptr, size_t size, size_t nmemb, void *userp)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;DBG(&quot;ptr = %s, userp = %sn&quot;, ptr, userp);
&nbsp;&nbsp;&nbsp;&nbsp;strcat(userp, ptr);

&nbsp;&nbsp;&nbsp;&nbsp;return size * nmemb; //必须返回这个大小, 否则只回调一次
&#125;
</textarea><br/><br/>整个代码如下：<br/><textarea name="code" class="php" rows="15" cols="100">
/*------------------------------------------------------------------------------------------
名称: http_cloud_curl_callbak.c
利用libcurl的API的回调机制实现云端通讯. http://curl.haxx.se/libcurl/c/curl_easy_setopt.html

CURLOPT_HEADERFUNCTION, CURLOPT_HEADERDATA: 只处理HTTP头部数据,处理与下载数据回调的处理相同.
&nbsp;&nbsp;&nbsp;&nbsp;sina的股票接口因为无HTTP头部返回因此不能应用此.
-------------------------------------------------------------------------------------------*/
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;curl/curl.h&gt;
#include &lt;assert.h&gt;

#include &quot;../http_cloud.h&quot;

#define CURL_HEADER (1)&nbsp;&nbsp;&nbsp;&nbsp;//0=利用 CURLOPT_WRITEFUNCTION, 1=利用 CURLOPT_HEADERFUNCTION
#define DBG printf
#define CURL_DBG (0)&nbsp;&nbsp;&nbsp;&nbsp;//1=开启curl的调试

//-----------------------------------------------------------------------------------------
static void get_local_time(char *pc_str)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;time_t now;
&nbsp;&nbsp;&nbsp;&nbsp;struct tm *timenow;

&nbsp;&nbsp;&nbsp;&nbsp;assert(pc_str != NULL);

&nbsp;&nbsp;&nbsp;&nbsp;time(&amp;now);
&nbsp;&nbsp;&nbsp;&nbsp;timenow = localtime(&amp;now);
&nbsp;&nbsp;&nbsp;&nbsp;sprintf(pc_str, &quot;%04d-%02d-%02dT%02d:%02d:%02d&quot;, timenow-&gt;tm_year+1900, timenow-&gt;tm_mon+1, timenow-&gt;tm_mday,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timenow-&gt;tm_hour, timenow-&gt;tm_min, timenow-&gt;tm_sec);
&#125;

size_t callback_get_head(void *ptr, size_t size, size_t nmemb, void *userp)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;DBG(&quot;ptr = %s, userp = %sn&quot;, ptr, userp);
&nbsp;&nbsp;&nbsp;&nbsp;strcat(userp, ptr);

&nbsp;&nbsp;&nbsp;&nbsp;return size * nmemb; //必须返回这个大小, 否则只回调一次
&#125;

static char connect_cloud(char *pc_ret, const char *host_addr, const int portno,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char *pc_method, struct curl_slist *http_headers)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;CURL *curl;
&nbsp;&nbsp;&nbsp;&nbsp;CURLcode res = CURLE_GOT_NOTHING;

&nbsp;&nbsp;assert((pc_ret != NULL) &amp;&amp; (host_addr != NULL) &amp;&amp; (http_headers != NULL) &amp;&amp; (pc_method != NULL));

&nbsp;&nbsp;//curl_global_init(CURL_GLOBAL_DEFAULT);
&nbsp;&nbsp;curl = curl_easy_init();
&nbsp;&nbsp;if (!curl)&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, &quot;--- curl init Error!n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
&nbsp;&nbsp;&#125;

&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_URL, host_addr);
&nbsp;&nbsp;curl_easy_setopt(curl, CURL_HTTP_VERSION_1_1, 1L);&nbsp;&nbsp;&nbsp;&nbsp;//HTTP 1.1
&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);&nbsp;&nbsp;&nbsp;&nbsp; //设置超时, 单位为秒
&nbsp;&nbsp;&nbsp;&nbsp;//curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);&nbsp;&nbsp;&nbsp;&nbsp; //屏蔽其它信号, makes libcurl NOT ask the system to ignore SIGPIPE signals

#if (CURL_DBG == 1)
&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);&nbsp;&nbsp;&nbsp;&nbsp;//调试用: 显示交互明细,
&nbsp;&nbsp;&nbsp;&nbsp;//curl_easy_setopt(curl, CURLOPT_HEADER, 1L);&nbsp;&nbsp;&nbsp;&nbsp;//调试用: 只显示头行的返回
#endif

#if 1
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, pc_method);

#if (CURL_HEADER == 0)
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_HEADER, 1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //下载数据包括HTTP头部, The default value for this parameter is 0.
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_get_head); //下载数据的回调函数
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_WRITEDATA, pc_ret);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//下载数据的指针

#else
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, callback_get_head); //头部数据的回调函数
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_HEADERDATA, pc_ret);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//头部数据的指针
#endif

&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_headers);&nbsp;&nbsp;&nbsp;&nbsp;//多行的HTTP头部
#endif

&nbsp;&nbsp;res = curl_easy_perform(curl);
&nbsp;&nbsp;if(res != CURLE_OK)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, &quot;curl_easy_perform() failed: %sn&quot;, curl_easy_strerror(res));

&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_cleanup(curl);

&nbsp;&nbsp;return 1;
&#125;

#if (YEELINK == 1)
int yeelink_create_data(const int device_id, const int sensor_id, const float device_value)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;char pc_ret[500], request[1024], pc_json[100], pc_time[30], pc_host_file[100], pc_header[100], pc_url[200], ret;
&nbsp;&nbsp;&nbsp;&nbsp;int len;

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(pc_host_file, &quot;v1.0/device/%d/sensor/%d/datapoints&quot;, device_id, sensor_id);
&nbsp;&nbsp;&nbsp;&nbsp;sprintf(pc_header, &quot;U-ApiKey: %s&quot;, YEELINK_API_KEY);

&nbsp;&nbsp;&nbsp;&nbsp;get_local_time(pc_time);
&nbsp;&nbsp;&nbsp;&nbsp;sprintf(pc_json, &quot;&#123;&quot;timestamp&quot;:&quot;%s&quot;,&quot;value&quot;:%.2f&#125;&quot;, pc_time, device_value);
&nbsp;&nbsp;&nbsp;&nbsp;len = strlen(pc_json);

&nbsp;&nbsp;&nbsp;&nbsp;//sprintf(request, &quot;POST /%s HTTP/1.1rnHost: %srnAccept: */*rn%srnContent-Length: %drnContent-Type: application/x-www-form-urlencodedrnConnection: Closernrn%srn&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;pc_host_file, YEELINK_HOST, pc_header, len, pc_json);
&nbsp;&nbsp;&nbsp;&nbsp;//DBG(&quot;request = %sn&quot;, request);

&nbsp;&nbsp;&nbsp;&nbsp;//组织请求头部, 自动末尾添加&#039;rn&#039;
&nbsp;&nbsp;&nbsp;&nbsp;struct curl_slist *http_headers = NULL;

&nbsp;&nbsp;&nbsp;&nbsp;//sprintf(request, &quot;POST /%s HTTP/1.1&quot;, pc_host_file);
&nbsp;&nbsp;&nbsp;&nbsp;//http_headers = curl_slist_append(http_headers, request);&nbsp;&nbsp;&nbsp;&nbsp;//此部分在url中体现

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;Host: %s&quot;, YEELINK_HOST);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;%s&quot;, pc_header);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;%s&quot;, &quot;Accept: */*&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;Content-Length: %d&quot;, len);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;%s&quot;, &quot;Content-Type: application/x-www-form-urlencoded&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;%s&quot;, &quot;Connection: Close&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;rn%s&quot;, pc_json);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

#if 0
&nbsp;&nbsp;&nbsp;&nbsp;struct curl_slist *tmp = http_headers;
&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;HTTP request = &quot;);
&nbsp;&nbsp;&nbsp;&nbsp;while(tmp) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;%sn&quot;, tmp-&gt;data);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp = tmp-&gt;next;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
#endif

&nbsp;&nbsp;&nbsp;&nbsp;//发送请求, 再判断返回值
&nbsp;&nbsp;&nbsp;&nbsp;//url = api.yeelink.net/v1.0/device/391/sensor/497/datapoints
&nbsp;&nbsp;&nbsp;&nbsp;sprintf(pc_url, &quot;%s/%s&quot;, YEELINK_HOST, pc_host_file);
&nbsp;&nbsp;&nbsp;&nbsp;ret = connect_cloud(pc_ret, pc_url, YEELINK_PORT, HTTP_POST, http_headers);

&nbsp;&nbsp;&nbsp;&nbsp;//释放 http_headers资源
&nbsp;&nbsp;&nbsp;&nbsp;curl_slist_free_all(http_headers);

&nbsp;&nbsp;&nbsp;&nbsp;DBG(&quot;yeelini ret = %sn&quot;, pc_ret);

&nbsp;&nbsp;&nbsp;&nbsp;return(ret);
&#125;
#endif

#if (LEWEI50 == 1)
//curl --request POST http://www.lewei50.com/api/V1/Gateway/UpdateSensors/01 --data &quot;[&#123;&quot;Name&quot;:&quot;T1&quot;,&quot;Value&quot;:&quot;23.08&quot;&#125;]&quot; --header &quot;userkey:36be8ff22f794f1e8a0bee3336eef237&quot;
int lewei50_create_data(const char *device_id, const float device_value)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;char pc_ret[500], request[1024], pc_json[100], pc_header[100], pc_url[200], *pc_data, ret;
&nbsp;&nbsp;&nbsp;&nbsp;int len;

&nbsp;&nbsp;&nbsp;&nbsp;assert(device_id != NULL);

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(pc_header, &quot;userkey: %s&quot;, LEWEI50_USER_KEY);
&nbsp;&nbsp;&nbsp;&nbsp;sprintf(pc_json, &quot;[&#123;&quot;Name&quot;:&quot;%s&quot;,&quot;Value&quot;:&quot;%.2f&quot;&#125;]&quot;, device_id, device_value);
&nbsp;&nbsp;&nbsp;&nbsp;len = strlen(pc_json);

&nbsp;&nbsp;&nbsp;&nbsp;//sprintf(request, &quot;POST /%s HTTP/1.1rnHost: %srnAccept: */*rn%srnContent-Length: %drnContent-Type: application/x-www-form-urlencodedrnConnection: Closernrn%srn&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;LEWEI50_HOST_FILE, LEWEI50_HOST, pc_header, len, pc_json);
&nbsp;&nbsp;&nbsp;&nbsp;//DBG(&quot;request = %sn&quot;, request);

&nbsp;&nbsp;&nbsp;&nbsp;//组织请求头部, 自动末尾添加&#039;rn&#039;
&nbsp;&nbsp;&nbsp;&nbsp;struct curl_slist *http_headers = NULL;

&nbsp;&nbsp;&nbsp;&nbsp;//sprintf(request, &quot;POST /%s HTTP/1.1&quot;, pc_host_file);
&nbsp;&nbsp;&nbsp;&nbsp;//http_headers = curl_slist_append(http_headers, request);&nbsp;&nbsp;&nbsp;&nbsp;//此部分在url中体现

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;Host: %s&quot;, LEWEI50_HOST);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;%s&quot;, pc_header);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;%s&quot;, &quot;Accept: */*&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;Content-Length: %d&quot;, len);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;%s&quot;, &quot;Content-Type: application/x-www-form-urlencoded&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;%s&quot;, &quot;Connection: Close&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

&nbsp;&nbsp;&nbsp;&nbsp;sprintf(request, &quot;rn%s&quot;, pc_json);
&nbsp;&nbsp;&nbsp;&nbsp;http_headers = curl_slist_append(http_headers, request);

&nbsp;&nbsp;&nbsp;&nbsp;//发送请求, 再判断返回值
&nbsp;&nbsp;&nbsp;&nbsp;//url = www.lewei50.com/api/V1/gateway/UpdateSensors/01
&nbsp;&nbsp;&nbsp;&nbsp;sprintf(pc_url, &quot;%s/%s&quot;, LEWEI50_HOST, LEWEI50_HOST_FILE);
&nbsp;&nbsp;&nbsp;&nbsp;ret = connect_cloud(pc_ret, pc_url, LEWEI50_PORT, HTTP_POST, http_headers);
&nbsp;&nbsp;&nbsp;&nbsp;//释放 http_headers资源
&nbsp;&nbsp;&nbsp;&nbsp;curl_slist_free_all(http_headers);

&nbsp;&nbsp;&nbsp;&nbsp;//&#123;&quot;Successful&quot;:true,&quot;Message&quot;:&quot;Successful. &quot;&#125;, 模式不同此返回数据的位置也不同.
&nbsp;&nbsp;&nbsp;&nbsp;DBG(&quot;lewei50 ret = %sn&quot;, pc_ret);
&nbsp;&nbsp;&nbsp;&nbsp;ret = 0;
&nbsp;&nbsp;&nbsp;&nbsp;pc_data = strstr(pc_ret, HTTP_RET_OK);
&nbsp;&nbsp;&nbsp;&nbsp;if (pc_data) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pc_data += strlen(HTTP_RET_OK);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//只返回最后的 json数据
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pc_data = strstr(pc_data, &quot;rnrn&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pc_data) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pc_data += 4;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = 1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DBG(&quot;lewei50 data = %sn&quot;, pc_data);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&nbsp;&nbsp;&nbsp;&nbsp;return(ret);
&#125;
#endif

//-------------------------------------------------------------------
int main(void)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;float f_value = 15.02;
&nbsp;&nbsp;&nbsp;&nbsp;int i_tmp;

&nbsp;&nbsp;&nbsp;&nbsp;time_t t;
&nbsp;&nbsp;srand((unsigned)time(&amp;t));&nbsp;&nbsp;&nbsp;&nbsp;//初始化随机种子, 否则随机数不随机

&nbsp;&nbsp;&nbsp;&nbsp;i_tmp = rand();
&nbsp;&nbsp;&nbsp;&nbsp;i_tmp -= (i_tmp &gt;&gt; 4 &lt;&lt; 4);
&nbsp;&nbsp;f_value += i_tmp;

#if (YEELINK == 1)
&nbsp;&nbsp;&nbsp;&nbsp;yeelink_create_data(YEELINK_DEVICE_ID, YEELINK_SENSOR_ID, f_value);
#endif

#if (LEWEI50 == 1)
&nbsp;&nbsp;&nbsp;&nbsp;lewei50_create_data(LEWEI50_DEVICE_ID, f_value);
#endif

&nbsp;&nbsp;&nbsp;&nbsp;return 1;
&#125;
</textarea><br/>From:<br/>http://www.ithao123.cn/content-1085192.html<br/><br/>curl连接超时的问题:<br/>CURLOPT_TIMEOUT&nbsp;&nbsp;设置cURL允许执行的最长秒数。&nbsp;&nbsp;<br/>CURLOPT_TIMEOUT_MS&nbsp;&nbsp;设置cURL允许执行的最长毫秒数。<br/>CURLOPT_CONNECTTIMEOUT&nbsp;&nbsp;在发起连接前等待的时间，如果设置为0，则无限等待。&nbsp;&nbsp;<br/>CURLOPT_CONNECTTIMEOUT_MS&nbsp;&nbsp;尝试连接等待的时间，以毫秒为单位。如果设置为0，则无限等待。<br/><br/>CURLOPT_CONNECTTIMEOUT 与 CURLOPT_CONNECTTIMEOUT_MS 类似,可以理解成等待连接成功创建的时间.<br/>来自：http://blog.chinaunix.net/uid-2270658-id-302245.html<br/>超时这一块还应该注意在不同的curl里存在毫秒，而上线后可能curl版本较低不支持毫秒，于是出现没有发出请求的问题：<br/>来自：http://www.vimer.cn/2012/01/%E5%85%B3%E4%BA%8Elibcurl%E4%B8%8D%E5%8F%91%E5%8C%85%E7%9A%84bug%E5%AE%9A%E4%BD%8D.html<br/><br/>使用libcurl库可以实现HTTP和FTP的请求，以前对http协议进行过学习，但一直无法很好的解决阻塞问题，认识了libcurl后方觉相见恨晚，因为http阻塞的问题已经困扰了我两年了。<br/>虽然编译出来的libcurl.lib足有700多K，但libcurl库的使用却很简单，只有熟悉curl_easy_setopt这个函数就可以了。该函数的作用是设置请求的相关参数来让curl构造协议头或返回指定的数据。<br/>//返回HTTP协议头<br/>curl_easy_setopt( curl, CURLOPT_HEADER, 1 );<br/>//超时设置（单位：秒），如果在指定时间内没数据可接收则超时<br/>curl_easy_setopt( curl, CURLOPT_TIMEOUT, 3 );<br/>//连接超时，不过只适用于Unix系统，Windows系统应该就是使用CURLOPT_TIMEOUT<br/>curl_easy_setopt( curl, CONNECTTIMEOUT, 3 );<br/>//设置请求Cookie<br/>curl_easy_setopt( curl, CURLOPT_COOKIE, cookie );<br/>//返回Cookie<br/>curl_easy_setopt( curl, CURLOPT_COOKIEJAR, cookie );<br/><br/>来自：http://blog.chinaunix.net/uid-2270658-id-247815.html<br/><br/>通常情况下，一般很少使用C语言来直接上传文件，但是遇到使用C语言编程实现文件上传时，该怎么做呢？<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;借助开源的libcurl库，我们可以容易地实现这个功能。Libcurl是一个免费易用的客户端URL传输库，主要功能是用不同的协议连接和沟通不同的服务器，libcurl当前支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP,IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet andTFTP。libcurl同样支持HTTPS证书授权，HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传，代理，cookies,和用户认证等。下面借鉴libcurl官网的例子完成简单的文件上传。<br/><br/>模拟要实现的文件上传FORM：<br/><br/><textarea name="code" class="php" rows="15" cols="100">
&lt;form action=&quot;fileUpload.action&quot; method=&quot;post&quot; enctype=&quot;multipart/form-data&quot;&gt;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File:&lt;input type=&quot;file&quot; name=&quot;sendfile&quot; /&gt;&lt;br&gt;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileName:&lt;input type=&quot;text&quot; name=&quot;filename&quot; /&gt;&lt;br&gt;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input type=&quot;submit&quot; name=&quot;submit&quot; value=&quot;Submit&quot; /&gt;&nbsp;&nbsp;
&lt;/form&gt;&nbsp;&nbsp;
</textarea><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其中，fileUpload.action为文件处理文件上传的接口，根据实际需要配置，这里只是一个例子。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C语言HTTP上传文件的代码如下：<br/><br/><textarea name="code" class="php" rows="15" cols="100">
#include &lt;stdio.h&gt;&nbsp;&nbsp;
#include &lt;string.h&gt;&nbsp;&nbsp;
#include &lt;curl/curl.h&gt;&nbsp;&nbsp;
&nbsp;&nbsp;
int main(int argc, char *argv[])&nbsp;&nbsp;
&#123;&nbsp;&nbsp;
&nbsp;&nbsp;CURL *curl;&nbsp;&nbsp;
&nbsp;&nbsp;CURLcode res;&nbsp;&nbsp;
&nbsp;&nbsp;
&nbsp;&nbsp;struct curl_httppost *formpost=NULL;&nbsp;&nbsp;
&nbsp;&nbsp;struct curl_httppost *lastptr=NULL;&nbsp;&nbsp;
&nbsp;&nbsp;struct curl_slist *headerlist=NULL;&nbsp;&nbsp;
&nbsp;&nbsp;static const char buf[] = &quot;Expect:&quot;;&nbsp;&nbsp;
&nbsp;&nbsp;
&nbsp;&nbsp;curl_global_init(CURL_GLOBAL_ALL);&nbsp;&nbsp;
&nbsp;&nbsp;
&nbsp;&nbsp;/* Fill in the file upload field */&nbsp;&nbsp;
&nbsp;&nbsp;curl_formadd(&amp;formpost,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;lastptr,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CURLFORM_COPYNAME, &quot;sendfile&quot;,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CURLFORM_FILE, &quot;D:&#92;&#92;sign.txt&quot;,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CURLFORM_END);&nbsp;&nbsp;
&nbsp;&nbsp;
&nbsp;&nbsp;/* Fill in the filename field */&nbsp;&nbsp;
&nbsp;&nbsp;curl_formadd(&amp;formpost,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;lastptr,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CURLFORM_COPYNAME, &quot;filename&quot;,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CURLFORM_COPYCONTENTS, &quot;sign.txt&quot;,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CURLFORM_END);&nbsp;&nbsp;
&nbsp;&nbsp;
&nbsp;&nbsp;/* Fill in the submit field too, even if this is rarely needed */&nbsp;&nbsp;
&nbsp;&nbsp;curl_formadd(&amp;formpost,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;lastptr,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CURLFORM_COPYNAME, &quot;submit&quot;,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CURLFORM_COPYCONTENTS, &quot;Submit&quot;,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CURLFORM_END);&nbsp;&nbsp;
&nbsp;&nbsp;
&nbsp;&nbsp;curl = curl_easy_init();&nbsp;&nbsp;
&nbsp;&nbsp;/* initalize custom header list (stating that Expect: 100-continue is not 
&nbsp;&nbsp;&nbsp;&nbsp; wanted */&nbsp;&nbsp;
&nbsp;&nbsp;headerlist = curl_slist_append(headerlist, buf);&nbsp;&nbsp;
&nbsp;&nbsp;if(curl) &#123;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;/* what URL that receives this POST */&nbsp;&nbsp;
&lt;span style=&quot;white-space:pre&quot;&gt;&nbsp;&nbsp;&lt;/span&gt;curl_easy_setopt(curl, CURLOPT_URL, &quot;http://localhost:8080/fileUpload.action&quot;);&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if ( (argc == 2) &amp;&amp; (!strcmp(argv[1], &quot;noexpectheader&quot;)) )&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* only disable 100-continue header if explicitly requested */&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);&nbsp;&nbsp;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;/* Perform the request, res will get the return code */&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;res = curl_easy_perform(curl);&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;/* Check for errors */&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if(res != CURLE_OK)&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, &quot;curl_easy_perform() failed: %s&#92;n&quot;,&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_strerror(res));&nbsp;&nbsp;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;/* always cleanup */&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;curl_easy_cleanup(curl);&nbsp;&nbsp;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;/* then cleanup the formpost chain */&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;curl_formfree(formpost);&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;/* free slist */&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;curl_slist_free_all (headerlist);&nbsp;&nbsp;
&nbsp;&nbsp;&#125;&nbsp;&nbsp;
&nbsp;&nbsp;return 0;&nbsp;&nbsp;
&#125;&nbsp;&nbsp;
</textarea><br/>代码经过测试，可以使用，但是需要提前配置好Libcur库，以及编译环境，这个自行google。代码很粗糙，功能很简单，只是起个抛砖引玉的作用，希望能对大家有所帮助。<br/>来自：http://blog.csdn.net/sxwyf248/article/details/7984776<br/>VC2013下，使用curl：<br/>http://www.tuicool.com/articles/A73ARr<br/>较细：http://blog.csdn.net/mjpassion/article/details/6290912<br/>Visual2012：http://www.howzhi.com/course/3387/lesson/43112<br/>参考：http://www.cppblog.com/len/archive/2008/06/21/54229.html<br/>使用libcurl模拟form表单上传的问题：<br/>http://bbs.csdn.net/topics/390817077<br/>在C语言程序中使用cURL库（libcurl）：<br/>http://demon.tw/programming/c-libcurl.html
]]>
</description>
</item><item>
<link>http://jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] [实践OK]C语言 HTTP上传文件-利用libcurl库上传文件, curl连接超时的问题 特别是获取返回头及内容的c写法。]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>