文章目录
- 前提摘要
- 给HTTP完整的一生
- 请求行
- 栗子
- 请求头部
- 空行
- 请求体
- 代码实现
前提摘要
上一章地址,点击浏览
给HTTP完整的一生
一个完整的HTTP请求至少需要以下几个部分
…
一、请求行.
二、请求头部.
三、空行.
四、请求体.
…
请求行
结构 > 请求方式 + 请求URL + HTTP协议版本
栗子
GET www.google.com HTTP/1.1
POST /interface/doc HTTP/1.0
#get或post请求方式,url使用绝对地址或相对地址
#HTTP1.1相比HTTP1.0,引入了持久连接,需要更多的系统资源,嵌入式不建议使用
#请求方式还有DELETE、PUT、HEAD、OPTIONS等
请求头部
Wireshark抓包分析
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml
Accept-Language: zh-CN
Connection: keep-alive
空行
\r\n\r\n
第一个 \r\n 是上一行内容需要换行,第二个 \r\n 是为了空出一行
请求体
{"name": "张三","age": 26
}
代码实现
为了一目了然,代码未拆分函数部分!
// 创建套接字int sock = socket(AF_INET, SOCK_STREAM, 0);if(sock < 0){return -1;}int millsec = 10000;struct timeval tv;tv.tv_sec = 0; // 超时时间设置为5秒tv.tv_usec = millsec*1000;if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const void*)&tv, sizeof(tv)) < 0) {printf("setsockopt failed\n");}if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&tv, sizeof(tv)) < 0) {printf("setsockopt failed\r\n");}struct sockaddr_in server_addr;struct hostent *server;server = gethostbyname("www.baidu.com");if(server == NULL) {printf("[ERROR] Get host ip failed\n");return -1;}// 设置服务器地址memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;memcpy(&server_addr.sin_addr.s_addr,server->h_addr,4);server_addr.sin_port = htons(80);int ret = 0;if (0 != (ret = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)))) {printf("sock_connect fail:%d\n", ret);return ret;}uint8_t http_uri[1024] = {0};sprintf(http_uri, "POST %s HTTP/1.0\r\nHost: %s\r\nAccept-Encoding: ''\r\nContent-Type: image/jpeg\r\nContent-Length: %d\r\n""deviceId: %s\r\ndeviceToken: %s\r\naction: start\r\nsid: %d\r\nstream: 1\r\n\r\n", ……);ret = send(sock, (void*)http_url, strlen(http_uri), 0); // send headerif(ret <= 0){if (sock_recv_timeout(sock)) {printf("sock_send\r\n"); return 0;}printf("sock_send failed ret = %d\r\n",ret);return -2;}uint8_t body_str[100] = {0};os_memcpy(body_str, "123", strlen("123"));ret = send(sock, (void*)body_str, strlen(body_str), 0);uint8_t rec_str[512] = {0};ret = recv(ai_sock, (void*)rec_str, len, 0); if(ret <= 0){printf("brush_http_recv failed:%d\r\n", ret);return -1;}if(strncmp(rec_str, "HTTP/", strlen("HTTP/")) != 0){printf("Not found HTTP\r\n");return -2;}uint8_t* p_ptr;p_ptr = rec_str+strlen("HTTP/1.1");if(atoi(p_ptr) != 200){printf("Bad HTTP Code:%d\r\n", atoi(p_ptr));return -2;}if((p_ptr = strstr(rec_str, "\r\n\r\n")) == NULL){printf("Not found http header\r\n");return -2;}p_ptr += strlen("\r\n\r\n");uint8_t* p_cnt_len;p_cnt_len = strstr(rec_str, "Content-Length:");if(p_cnt_len){p_cnt_len += strlen("Content-Length:");cnt_len = atoi(p_cnt_len); ret -= (p_ptr-rec_str);if(cnt_len != ret){printf("Content-Length mismatch:%d/%d\r\n", cnt_len, ret); brush_error = BLE_wifi_state_photo_upload_error; goto HTTP_FAILED;}}
先写到这,静待下一章!