1. libcurl 的参考文档如下

CURLOPT_HEADERFUNCTION

Pass a pointer to a function that matches the following prototype: size_t function( void *ptr, size_t size, size_t nmemb, void *userdata);. This function gets called by libcurl as soon as it has received header data. The header callback will be called once for each header and only complete header lines are passed on to the callback. Parsing headers is very easy using this. The size of the data pointed to by ptr is sizemultiplied with nmemb. Do not assume that the header line is zero terminated! The pointer named userdata is the one you set with the CURLOPT_WRITEHEADER option. The callback function must return the number of bytes actually taken care of. If that amount differs from the amount passed to your function, it'll signal an error to the library. This will abort the transfer and return CURL_WRITE_ERROR.

A complete HTTP header that is passed to this function can be up to CURL_MAX_HTTP_HEADER (100K) bytes.

If this option is not set, or if it is set to NULL, but CURLOPT_HEADERDATA (CURLOPT_WRITEHEADER) is set to anything but NULL, the function used to accept response data will be used instead. That is, it will be the function specified with CURLOPT_WRITEFUNCTION, or if it is not specified or NULL - the default, stream-writing function.

It's important to note that the callback will be invoked for the headers of all responses received after initiating a request and not just the final response. This includes all responses which occur during authentication negotiation. If you need to operate on only the headers from the final response, you will need to collect headers in the callback yourself and use HTTP status lines, for example, to delimit response boundaries.

When a server sends a chunked encoded transfer, it may contain a trailer. That trailer is identical to a HTTP header and if such a trailer is received it is passed to the application using this callback as well. There are several ways to detect it being a trailer and not an ordinary header: 1) it comes after the response-body. 2) it comes after the final header line (CR LF) 3) a Trailer: header among the regular response-headers mention what header(s) to expect in the trailer.

For non-HTTP protocols like FTP, POP3, IMAP and SMTP this function will get called with the server responses to the commands that libcurl sends.

CURLOPT_WRITEHEADER

(This option is also known as CURLOPT_HEADERDATA) Pass a pointer to be used to write the header part of the received data to. If you don't use CURLOPT_WRITEFUNCTION or CURLOPT_HEADERFUNCTIONto take care of the writing, this must be a valid FILE * as the internal default will then be a plain fwrite(). See also the CURLOPT_HEADERFUNCTION option above on how to set a custom get-all-headers callback.

2. 完整code如下

点击(此处)折叠或打开

  1. /*------------------------------------------------------------------------------------------
  2. 名称: http_cloud_curl_callbak.c
  3. 利用libcurl的API的回调机制实现云端通讯. http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
  4. CURLOPT_HEADERFUNCTION, CURLOPT_HEADERDATA: 只处理HTTP头部数据,处理与下载数据回调的处理相同.
  5. sina的股票接口因为无HTTP头部返回因此不能应用此.
  6. -------------------------------------------------------------------------------------------*/
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <curl/curl.h>
  11. #include <assert.h>
  12. #include "../http_cloud.h"
  13. #define CURL_HEADER (1)    //0=利用 CURLOPT_WRITEFUNCTION, 1=利用 CURLOPT_HEADERFUNCTION
  14. #define DBG printf
  15. #define CURL_DBG (0)    //1=开启curl的调试
  16. //-----------------------------------------------------------------------------------------
  17. static void get_local_time(char *pc_str)
  18. {
  19. time_t now;
  20. struct tm *timenow;
  21. assert(pc_str != NULL);
  22. time(&now);
  23. timenow = localtime(&now);
  24. sprintf(pc_str, "%04d-%02d-%02dT%02d:%02d:%02d", timenow->tm_year+1900, timenow->tm_mon+1, timenow->tm_mday,
  25. timenow->tm_hour, timenow->tm_min, timenow->tm_sec);
  26. }
  27. size_t callback_get_head(void *ptr, size_t size, size_t nmemb, void *userp)
  28. {
  29. DBG("ptr = %s, userp = %s\n", ptr, userp);
  30. strcat(userp, ptr);
  31. return size * nmemb; //必须返回这个大小, 否则只回调一次
  32. }
  33. static char connect_cloud(char *pc_ret, const char *host_addr, const int portno,
  34. const char *pc_method, struct curl_slist *http_headers)
  35. {
  36. CURL *curl;
  37. CURLcode res = CURLE_GOT_NOTHING;
  38. assert((pc_ret != NULL) && (host_addr != NULL) && (http_headers != NULL) && (pc_method != NULL));
  39. //curl_global_init(CURL_GLOBAL_DEFAULT);
  40. curl = curl_easy_init();
  41. if (!curl)    {
  42. fprintf(stderr, "--- curl init Error!\n");
  43. return 0;
  44. }
  45. curl_easy_setopt(curl, CURLOPT_URL, host_addr);
  46. curl_easy_setopt(curl, CURL_HTTP_VERSION_1_1, 1L);    //HTTP 1.1
  47. curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);     //设置超时, 单位为秒
  48. //curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);     //屏蔽其它信号, makes libcurl NOT ask the system to ignore SIGPIPE signals
  49. #if (CURL_DBG == 1)
  50. curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);    //调试用: 显示交互明细,
  51. //curl_easy_setopt(curl, CURLOPT_HEADER, 1L);    //调试用: 只显示头行的返回
  52. #endif
  53. #if 1
  54. curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, pc_method);
  55. #if (CURL_HEADER == 0)
  56. curl_easy_setopt(curl, CURLOPT_HEADER, 1);         //下载数据包括HTTP头部, The default value for this parameter is 0.
  57. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_get_head); //下载数据的回调函数
  58. curl_easy_setopt(curl, CURLOPT_WRITEDATA, pc_ret);                                //下载数据的指针
  59. #else
  60. curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, callback_get_head); //头部数据的回调函数
  61. curl_easy_setopt(curl, CURLOPT_HEADERDATA, pc_ret);                                //头部数据的指针
  62. #endif
  63. curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_headers);    //多行的HTTP头部
  64. #endif
  65. res = curl_easy_perform(curl);
  66. if(res != CURLE_OK)
  67. fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
  68. curl_easy_cleanup(curl);
  69. return 1;
  70. }
  71. #if (YEELINK == 1)
  72. int yeelink_create_data(const int device_id, const int sensor_id, const float device_value)
  73. {
  74. char pc_ret[500], request[1024], pc_json[100], pc_time[30], pc_host_file[100], pc_header[100], pc_url[200], ret;
  75. int len;
  76. sprintf(pc_host_file, "v1.0/device/%d/sensor/%d/datapoints", device_id, sensor_id);
  77. sprintf(pc_header, "U-ApiKey: %s", YEELINK_API_KEY);
  78. get_local_time(pc_time);
  79. sprintf(pc_json, "{\"timestamp\":\"%s\",\"value\":%.2f}", pc_time, device_value);
  80. len = strlen(pc_json);
  81. //sprintf(request, "POST /%s HTTP/1.1\r\nHost: %s\r\nAccept: */*\r\n%s\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\nConnection: Close\r\n\r\n%s\r\n",
  82. //    pc_host_file, YEELINK_HOST, pc_header, len, pc_json);
  83. //DBG("request = %s\n", request);
  84. //组织请求头部, 自动末尾添加'\r\n'
  85. struct curl_slist *http_headers = NULL;
  86. //sprintf(request, "POST /%s HTTP/1.1", pc_host_file);
  87. //http_headers = curl_slist_append(http_headers, request);    //此部分在url中体现
  88. sprintf(request, "Host: %s", YEELINK_HOST);
  89. http_headers = curl_slist_append(http_headers, request);
  90. sprintf(request, "%s", pc_header);
  91. http_headers = curl_slist_append(http_headers, request);
  92. sprintf(request, "%s", "Accept: */*");
  93. http_headers = curl_slist_append(http_headers, request);
  94. sprintf(request, "Content-Length: %d", len);
  95. http_headers = curl_slist_append(http_headers, request);
  96. sprintf(request, "%s", "Content-Type: application/x-www-form-urlencoded");
  97. http_headers = curl_slist_append(http_headers, request);
  98. sprintf(request, "%s", "Connection: Close");
  99. http_headers = curl_slist_append(http_headers, request);
  100. sprintf(request, "\r\n%s", pc_json);
  101. http_headers = curl_slist_append(http_headers, request);
  102. #if 0
  103. struct curl_slist *tmp = http_headers;
  104. printf("HTTP request = ");
  105. while(tmp) {
  106. printf("%s\n", tmp->data);
  107. tmp = tmp->next;
  108. }
  109. #endif
  110. //发送请求, 再判断返回值
  111. //url = api.yeelink.net/v1.0/device/391/sensor/497/datapoints
  112. sprintf(pc_url, "%s/%s", YEELINK_HOST, pc_host_file);
  113. ret = connect_cloud(pc_ret, pc_url, YEELINK_PORT, HTTP_POST, http_headers);
  114. //释放 http_headers资源
  115. curl_slist_free_all(http_headers);
  116. DBG("yeelini ret = %s\n", pc_ret);
  117. return(ret);
  118. }
  119. #endif
  120. #if (LEWEI50 == 1)
  121. //curl --request POST http://www.lewei50.com/api/V1/Gateway/UpdateSensors/01 --data "[{\"Name\":\"T1\",\"Value\":\"23.08\"}]" --header "userkey:36be8ff22f794f1e8a0bee3336eef237"
  122. int lewei50_create_data(const char *device_id, const float device_value)
  123. {
  124. char pc_ret[500], request[1024], pc_json[100], pc_header[100], pc_url[200], *pc_data, ret;
  125. int len;
  126. assert(device_id != NULL);
  127. sprintf(pc_header, "userkey: %s", LEWEI50_USER_KEY);
  128. sprintf(pc_json, "[{\"Name\":\"%s\",\"Value\":\"%.2f\"}]", device_id, device_value);
  129. len = strlen(pc_json);
  130. //sprintf(request, "POST /%s HTTP/1.1\r\nHost: %s\r\nAccept: */*\r\n%s\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\nConnection: Close\r\n\r\n%s\r\n",
  131. //    LEWEI50_HOST_FILE, LEWEI50_HOST, pc_header, len, pc_json);
  132. //DBG("request = %s\n", request);
  133. //组织请求头部, 自动末尾添加'\r\n'
  134. struct curl_slist *http_headers = NULL;
  135. //sprintf(request, "POST /%s HTTP/1.1", pc_host_file);
  136. //http_headers = curl_slist_append(http_headers, request);    //此部分在url中体现
  137. sprintf(request, "Host: %s", LEWEI50_HOST);
  138. http_headers = curl_slist_append(http_headers, request);
  139. sprintf(request, "%s", pc_header);
  140. http_headers = curl_slist_append(http_headers, request);
  141. sprintf(request, "%s", "Accept: */*");
  142. http_headers = curl_slist_append(http_headers, request);
  143. sprintf(request, "Content-Length: %d", len);
  144. http_headers = curl_slist_append(http_headers, request);
  145. sprintf(request, "%s", "Content-Type: application/x-www-form-urlencoded");
  146. http_headers = curl_slist_append(http_headers, request);
  147. sprintf(request, "%s", "Connection: Close");
  148. http_headers = curl_slist_append(http_headers, request);
  149. sprintf(request, "\r\n%s", pc_json);
  150. http_headers = curl_slist_append(http_headers, request);
  151. //发送请求, 再判断返回值
  152. //url = www.lewei50.com/api/V1/gateway/UpdateSensors/01
  153. sprintf(pc_url, "%s/%s", LEWEI50_HOST, LEWEI50_HOST_FILE);
  154. ret = connect_cloud(pc_ret, pc_url, LEWEI50_PORT, HTTP_POST, http_headers);
  155. //释放 http_headers资源
  156. curl_slist_free_all(http_headers);
  157. //{"Successful":true,"Message":"Successful. "}, 模式不同此返回数据的位置也不同.
  158. DBG("lewei50 ret = %s\n", pc_ret);
  159. ret = 0;
  160. pc_data = strstr(pc_ret, HTTP_RET_OK);
  161. if (pc_data) {
  162. pc_data += strlen(HTTP_RET_OK);
  163. //只返回最后的 json数据
  164. pc_data = strstr(pc_data, "\r\n\r\n");
  165. if (pc_data) {
  166. pc_data += 4;
  167. ret = 1;
  168. DBG("lewei50 data = %s\n", pc_data);
  169. }
  170. }
  171. return(ret);
  172. }
  173. #endif
  174. //-------------------------------------------------------------------
  175. int main(void)
  176. {
  177. float f_value = 15.02;
  178. int i_tmp;
  179. time_t t;
  180. srand((unsigned)time(&t));    //初始化随机种子, 否则随机数不随机
  181. i_tmp = rand();
  182. i_tmp -= (i_tmp >> 4 << 4);
  183. f_value += i_tmp;
  184. #if (YEELINK == 1)
  185. yeelink_create_data(YEELINK_DEVICE_ID, YEELINK_SENSOR_ID, f_value);
  186. #endif
  187. #if (LEWEI50 == 1)
  188. lewei50_create_data(LEWEI50_DEVICE_ID, f_value);
  189. #endif
  190. return 1;
  191. }

3.  Makefile如下

点击(此处)折叠或打开

  1. OPENWRT = 1
  2. ifeq ($(OPENWRT), 1)
  3. CC = ~/OpenWrt-SDK-ar71xx-for-linux-i486-gcc-4.6-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-gcc
  4. CFLAGS += -I ~/openwrt-lib/include -L ~/openwrt-lib/lib
  5. LFLAGS += -lcurl -lcrypto -lz -lssl
  6. else
  7. CC = gcc
  8. LFLAGS += -lcurl
  9. endif
  10. CFLAGS += -Wall -O2
  11. #CFLAGS += -g
  12. #可执行文件名和相关的obj文件
  13. APP_BINARY = http_cloud
  14. SRCS += http_cloud_curl_callback.c
  15. OBJS = $(SRCS:.c=.o)
  16. all: APP_FILE
  17. APP_FILE: $(OBJS)
  18. $(CC) $(CFLAGS) $(OBJS) -o $(APP_BINARY) $(LFLAGS)
  19. .PHONY: clean
  20. clean:
  21. @echo "cleanning project"
  22. $(RM) *.a $(OBJS) *~ *.so *.lo $(APP_BINARY)
  23. @echo "clean completed"

4. 运行结果如下
xxg@xxg-desktop:~/1-wire/http_cloud/libcurl$ ./http_cloud
ptr = HTTP/1.1 200 OK
, userp = 
ptr = Server: nginx/1.1.19
, userp = HTTP/1.1 200 OK

ptr = Date: Mon, 25 Nov 2013 01:29:37 GMT
, userp = HTTP/1.1 200 OK
Server: nginx/1.1.19

ptr = Content-Type: text/html
, userp = HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Mon, 25 Nov 2013 01:29:37 GMT

ptr = Transfer-Encoding: chunked
, userp = HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Mon, 25 Nov 2013 01:29:37 GMT
Content-Type: text/html

ptr = Connection: close
, userp = HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Mon, 25 Nov 2013 01:29:37 GMT
Content-Type: text/html
Transfer-Encoding: chunked

ptr = X-Powered-By: PHP/5.3.10-1ubuntu3.6
, userp = HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Mon, 25 Nov 2013 01:29:37 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: close

ptr = Set-Cookie: CAKEPHP=kgqv6b4rnbbtn1h1ndda514936; expires=Tue, 03-Dec-2013 09:29:37 GMT; path=/
, userp = HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Mon, 25 Nov 2013 01:29:37 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: close
X-Powered-By: PHP/5.3.10-1ubuntu3.6

ptr = P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"
, userp = HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Mon, 25 Nov 2013 01:29:37 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: close
X-Powered-By: PHP/5.3.10-1ubuntu3.6
Set-Cookie: CAKEPHP=kgqv6b4rnbbtn1h1ndda514936; expires=Tue, 03-Dec-2013 09:29:37 GMT; path=/

ptr = 
, userp = HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Mon, 25 Nov 2013 01:29:37 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: close
X-Powered-By: PHP/5.3.10-1ubuntu3.6
Set-Cookie: CAKEPHP=kgqv6b4rnbbtn1h1ndda514936; expires=Tue, 03-Dec-2013 09:29:37 GMT; path=/
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

yeelini ret = HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Mon, 25 Nov 2013 01:29:37 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: close
X-Powered-By: PHP/5.3.10-1ubuntu3.6
Set-Cookie: CAKEPHP=kgqv6b4rnbbtn1h1ndda514936; expires=Tue, 03-Dec-2013 09:29:37 GMT; path=/
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

ptr = HTTP/1.1 200 OK
, userp = onnection: close
X-Powered-By: PHP/5.3.10-1ubuntu3.6
Set-Cookie: CAKEPHP=kgqv6b4rnbbtn1h1ndda514936; expires=Tue, 03-Dec-2013 09:29:37 GMT; path=/
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

ptr = Date: Mon, 25 Nov 2013 01:29:37 GMT
, userp = onnection: close
X-Powered-By: PHP/5.3.10-1ubuntu3.6
Set-Cookie: CAKEPHP=kgqv6b4rnbbtn1h1ndda514936; expires=Tue, 03-Dec-2013 09:29:37 GMT; path=/
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

HTTP/1.1 200 OK

ptr = Content-Type: application/json; charset=utf-8
, userp = onnection: close
X-Powered-By: PHP/5.3.10-1ubuntu3.6
Set-Cookie: CAKEPHP=kgqv6b4rnbbtn1h1ndda514936; expires=Tue, 03-Dec-2013 09:29:37 GMT; path=/
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 01:29:37 GMT

ptr = Content-Length: 44
, userp = onnection: close
X-Powered-By: PHP/5.3.10-1ubuntu3.6
Set-Cookie: CAKEPHP=kgqv6b4rnbbtn1h1ndda514936; expires=Tue, 03-Dec-2013 09:29:37 GMT; path=/
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 01:29:37 GMT
Content-Type: application/json; charset=utf-8

ptr = Connection: close
, userp = onnection: close
X-Powered-By: PHP/5.3.10-1ubuntu3.6
Set-Cookie: CAKEPHP=kgqv6b4rnbbtn1h1ndda514936; expires=Tue, 03-Dec-2013 09:29:37 GMT; path=/
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 01:29:37 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 44

ptr = Cache-Control: private
, userp = onnection: close
X-Powered-By: PHP/5.3.10-1ubuntu3.6
Set-Cookie: CAKEPHP=kgqv6b4rnbbtn1h1ndda514936; expires=Tue, 03-Dec-2013 09:29:37 GMT; path=/
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 01:29:37 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 44
Connection: close

ptr = Set-Cookie: SERVERID=a4a5b2bbca16d8c8b2ba6d5b6e55f36e|1385342977|1385342977;Path=/
, userp = onnection: close
X-Powered-By: PHP/5.3.10-1ubuntu3.6
Set-Cookie: CAKEPHP=kgqv6b4rnbbtn1h1ndda514936; expires=Tue, 03-Dec-2013 09:29:37 GMT; path=/
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 01:29:37 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 44
Connection: close
Cache-Control: private

ptr = 
, userp = onnection: close
X-Powered-By: PHP/5.3.10-1ubuntu3.6
Set-Cookie: CAKEPHP=kgqv6b4rnbbtn1h1ndda514936; expires=Tue, 03-Dec-2013 09:29:37 GMT; path=/
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 01:29:37 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 44
Connection: close
Cache-Control: private
Set-Cookie: SERVERID=a4a5b2bbca16d8c8b2ba6d5b6e55f36e|1385342977|1385342977;Path=/

{"Successful":true,"Message":"Successful. "}lewei50 ret = onnection: close
X-Powered-By: PHP/5.3.10-1ubuntu3.6
Set-Cookie: CAKEPHP=kgqv6b4rnbbtn1h1ndda514936; expires=Tue, 03-Dec-2013 09:29:37 GMT; path=/
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 01:29:37 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 44
Connection: close
Cache-Control: private
Set-Cookie: SERVERID=a4a5b2bbca16d8c8b2ba6d5b6e55f36e|1385342977|1385342977;Path=/

lewei50 data =

xxg@xxg-desktop:~/1-wire/http_cloud/libcurl$

(转)利用libcurl和国内著名的两个物联网云端通讯的例程, ubuntu和openwrt下调试成功(四)的更多相关文章

  1. (转)利用libcurl获取新浪股票接口, ubuntu和openwrt实验成功(三)

    1.  利用 CURLOPT_WRITEFUNCTION 设置回调函数, 利用 CURLOPT_WRITEDATA 获取数据指针 官网文档如下 CALLBACK OPTIONS CURLOPT_WRI ...

  2. 利用Windows 2003系统中实现两个网段的路由

    利用Windows 2003系统中实现两个网段的路由 当一个局域网中存在两个以上网段时,分属于不同网段内的主机彼此互不可见.为了解决这个问 题,就必须在不同的网段之间设置路由器.如果花费上万元资金购买 ...

  3. app开发团队人员构成怎么分配?国内著名的app开发团队有哪些

    app开发团队人员构成:作为一个独立的app开发团队,人员架构必须包括产品经理,程序开发人员,测试专员,运营团队,UI 设计.这里是对专业的App开发公司而言,一般个人或团队可能一个人会身兼多职,所以 ...

  4. 国内首篇介绍JanOS物联网操作系统的文章 - 如何把你的手机主板打造成物联网平台

    天地会珠海分舵注:如无意外,您现在正在看的将是国内首篇且是唯一一篇介绍炙手可热的物联网的操作系统JanOS的文章!不信你去百度!希望大家能喜欢.但本文只是引言,更多信息请还是访问JanOS的官网:ht ...

  5. 客户端技术的一点思考(数据存储用SQLite, XMPP通讯用Gloox, Web交互用LibCurl, 数据打包用Protocol Buffer, socket通讯用boost asio)

    今天看到CSDN上这么一篇< 彻底放弃没落的MFC,对新人的忠告!>, 作为一个一直在Windows上搞客户端开发的C++程序员,几年前也有过类似的隐忧(参见 落伍的感觉), 现在却有一些 ...

  6. C语言:假定输入的字符串只包含字母和*号,fun函数:除了尾部的*号以外,将字符的其他*号进行全部删除,形参p已经指向字符串中最后一个字母。-利用折半查找整数m在有序数组中的位置,若找到,返回下标值,否则返回-1。

    //假定输入的字符串只包含字母和*号,fun函数:除了尾部的*号以外,将字符的其他*号进行全部删除,形参p已经指向字符串中最后一个字母. #include <stdio.h> void f ...

  7. 利用深搜和宽搜两种算法解决TreeView控件加载文件的问题。

    利用TreeView控件加载文件,必须遍历处所有的文件和文件夹. 深搜算法用到了递归. using System; using System.Collections.Generic; using Sy ...

  8. 国内流行的两大开源.net微信公众平台SDK对比分析

    最近忙于微信周边的开发 难免手痒去搜索一下有没有相关的sdk直接拿来使 还真发现了不少 这里总结两个看起来比较不错的.net平台下基于C#语言开发的SDK 一个强大一个小巧 (1) Senparc.W ...

  9. C语言 HTTP上传文件-利用libcurl库上传文件

    原文  http://justwinit.cn/post/7626/ 通常情况下,一般很少使用C语言来直接上传文件,但是遇到使用C语言编程实现文件上传时,该怎么做呢? 借助开源的libcurl库,我们 ...

随机推荐

  1. 03.SQLServer性能优化之---存储优化系列

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 概  述:http://www.cnblogs.com/dunitian/p/60413 ...

  2. 理解CSS边框border

    前面的话   边框是CSS盒模型属性中默默无闻的一个普通属性,CSS3的到来,但得边框属性重新焕发了光彩.本文将详细介绍CSS边框 基础样式   边框是一条以空格分隔的集合样式,包括边框粗细(边框宽度 ...

  3. JavaScript Object对象

    目录 1. 介绍:阐述 Object 对象. 2. 构造函数:介绍 Object 对象的构造函数. 3. 实例属性:介绍 Object 对象的实例属性:prototype.constructor等等. ...

  4. Matlab数值计算示例: 牛顿插值法、LU分解法、拉格朗日插值法、牛顿插值法

    本文源于一次课题作业,部分自己写的,部分借用了网上的demo 牛顿迭代法(1) x=1:0.01:2; y=x.^3-x.^2+sin(x)-1; plot(x,y,'linewidth',2);gr ...

  5. scrapy 知乎用户信息爬虫

    zhihu_spider 此项目的功能是爬取知乎用户信息以及人际拓扑关系,爬虫框架使用scrapy,数据存储使用mongo,下载这些数据感觉也没什么用,就当为大家学习scrapy提供一个例子吧.代码地 ...

  6. 用scikit-learn学习BIRCH聚类

    在BIRCH聚类算法原理中,我们对BIRCH聚类算法的原理做了总结,本文就对scikit-learn中BIRCH算法的使用做一个总结. 1. scikit-learn之BIRCH类 在scikit-l ...

  7. 【HanLP】资料链接汇总

    Java中调用HanLP配置 HanLP自然语言处理包开源官方文档 了解HanLP的全部 自然语言处理HanLP 开源自由的汉语言处理包主页 GitHub源码 基于hanLP的中文分词详解-MapRe ...

  8. 介绍一款原创的四则运算算式生成器:CalculateIt2

    家里小朋友读一年级了,最近每天都有一些10以内的加减法口算练习,作为程序员爸爸,自然也是想办法能够偷懒,让电脑出题,给小朋友做些练习.于是,自己在业余时间开发了一个四则运算算式生成器,名为:Calcu ...

  9. Django admin定制化,User字段扩展[原创]

    前言 参考上篇博文,我们利用了OneToOneField的方式使用了django自带的user,http://www.cnblogs.com/caseast/p/5909248.html , 但这么用 ...

  10. C#使用GET、POST请求获取结果

    C#使用GET.POST请求获取结果,这里以一个简单的用户登陆为例. 1. 使用GET请求获取结果 1.1 创建LoginHandler.aspx处理页面 protected void Page_Lo ...