#include "board.h" #include #include #include #include "FreeRTOS.h" #include "api.h" #include "sockets.h" #define HOST_NAME "www.baidu.com" const static char get_buf[]= "GET / HTTP/1.1\r\n" /* HOST, host-port, URI */\ "Host: www.baidu.com\r\n" /* server name */ \ "\r\n"; /* *行长度不包含行尾的\r\n */ static int https_content_get_line_len(const char *https_content, int content_len) { int ret = -1; int step = 0; int cnt; if (!https_content || (content_len <= 0)) goto exit; for (cnt = 0; cnt < content_len; cnt++) { if (https_content[cnt] == '\r') { step = 1; } else if (https_content[cnt] == '\n') { if (step == 1) { ret = cnt - 1; break; } } else { step = 0; } } exit: return ret; } static int https_content_get_line_pos(const char *https_content, int content_len, uint32_t line) { int pos = -1; int cur_pos; int step = 0; int line_cnt = 0; if (!https_content || (content_len <= 0)) goto exit; for (cur_pos = 0; cur_pos < content_len; cur_pos++) { if (step == 2) { line_cnt++; step = 0; if (line_cnt == line) { pos = cur_pos; break; } } if (https_content[cur_pos] == '\r') { step = 1; } else if (https_content[cur_pos] == '\n') { if (step == 1) { step = 2; } } else { step = 0; } } exit: return pos; } static int https_get_content_length(const char *https_content, int content_len) { int ret = -1; int line_len = 0; int pos = 0; int pos_cnt = 0; const char header_start[] = "HTTP"; const char ContentLength[] = "Content-Length"; if (!https_content || content_len < 4) { ret = -1; goto exit; } if (memcmp((const void *)https_content, (const void *)header_start, 4) != 0) { ret = -1; goto exit; } while (1) { pos = https_content_get_line_pos(&https_content[pos_cnt], content_len - pos_cnt, 1); if (pos > -1) { pos_cnt += pos; line_len = https_content_get_line_len(&https_content[pos_cnt], content_len - pos_cnt); if (line_len <= 0) { break; } else if (line_len >= strlen(ContentLength)) { if (memcmp((const char *)&https_content[pos_cnt], (const char *)ContentLength, strlen(ContentLength)) == 0) { sscanf((const char *)&https_content[pos_cnt + strlen(ContentLength) + 2], (const char *)"%d\r\n", &ret); break; } } } else { break; } } exit: return ret; } static int https_get_content_pos(const char *https_content, int content_len) { int ret = -1; int line_len = 0; int pos = 0; int pos_cnt = 0; int flag = 0; const char header_start[] = "HTTP"; if (!https_content || content_len < 4) { ret = -1; goto exit; } if (memcmp((const void *)https_content, (const void *)header_start, 4) != 0) { ret = -1; goto exit; } while (1) { pos = https_content_get_line_pos(&https_content[pos_cnt], content_len - pos_cnt, 1); if (pos > -1) { pos_cnt += pos; line_len = https_content_get_line_len(&https_content[pos_cnt], content_len - pos_cnt); if (flag) { ret = pos_cnt; break; } else { if (line_len < 0) { break; } else if (line_len == 0) { flag = 1; } } } else { break; } } exit: return ret; } void http_client_test(void *thread_param) { err_t err = ERR_OK; int sock = -1; struct sockaddr_in client_addr; char *rbuf = NULL; int total_recv_len = 0; uint32_t pg_size = 1024 * 16; int ContentLength = -1; int content_start_pos = -1; int recv_len = 0; printf("-------------- lwip http client test ---------------\n"); char* host_ip; ip4_addr_t dns_ip; err = netconn_gethostbyname(HOST_NAME, &dns_ip); if (err != ERR_OK) { printf("-------------- netconn_gethostbyname fail! --------------\n"); goto exit; } host_ip = ip_ntoa(&dns_ip); printf("host name : %s , host_ip : %s\n",HOST_NAME,host_ip); sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { printf("Socket error\n"); goto exit; } client_addr.sin_family = AF_INET; client_addr.sin_port = htons(80); client_addr.sin_addr.s_addr = inet_addr(host_ip); memset(&(client_addr.sin_zero), 0, sizeof(client_addr.sin_zero)); if (connect(sock, (struct sockaddr *)&client_addr, sizeof(client_addr)) == -1) { printf("Connect failed!\n"); goto exit; } printf("Connect to server successful!\n"); printf("\n***************************************************\n"); write(sock,get_buf,sizeof(get_buf)); //接收 for(;;) { if (total_recv_len == 0) rbuf = (char *)pvPortRealloc(rbuf, pg_size); else rbuf = (char *)pvPortRealloc(rbuf, total_recv_len + pg_size); if (!rbuf) { printf("realloc fail!\n"); goto exit; } if ((ContentLength > 0) && (content_start_pos > 0)) { if (((ContentLength + content_start_pos) - total_recv_len) >= pg_size) { recv_len = recv(sock, rbuf + total_recv_len, pg_size, 0); } else { recv_len = recv(sock, rbuf + total_recv_len, ((ContentLength + content_start_pos) - total_recv_len), 0); } } else { recv_len = recv(sock, rbuf + total_recv_len, pg_size, 0); } if(recv_len <= 0) { break; } total_recv_len += recv_len; if ((ContentLength > 0) && (content_start_pos > 0)) { if ((ContentLength + content_start_pos) <= total_recv_len) break; } if (ContentLength == -1) { ContentLength = https_get_content_length((const char *)rbuf, total_recv_len); if (ContentLength > 0) printf("ContentLength = %d\n", ContentLength); } if ((ContentLength > 0) && (content_start_pos == -1)) { content_start_pos = https_get_content_pos((const char *)rbuf, total_recv_len); if (content_start_pos > 0) printf("content_start_pos = %d\n", content_start_pos); } } printf("\n ========== \n\n"); printf("https recv data : recv_len = 0x%x!\n",total_recv_len); printf("addr:0x%x\n", (uint32_t)rbuf); printf("\n ========== \n\n"); printf("\n**************************************************\n"); exit: if (sock >= 0) closesocket(sock); if (rbuf) vPortFree((void *)rbuf); }