嵌入式学习的第三十五天-进程间通信-HTTP
TCP/IP协议模型:应用层:HTTP;传输层:TCP UDP;网络层:IPv4 IPv6
网络接口层
一、HTTP协议
1. 万维网
WWW(World Wide Web)
世界范围内的,联机式的信息储藏所。
万维网解决了获取互联网上的数据时需要解决的以下问题:
(1)怎样标识分布在整个互联网上的文档 URL------万维网服务端如何区分请求的数据
(2)用什么样的协议实现万维网上的各种链接 HTTP-----万维网服务端与服务器之间如何通信
(3)怎么使用户能够方便的查看文档数据 HTML(超文本标记语言) ----浏览器端如何展示请求到的万维网数据
2.URL
统一资源定位符 表示从因特网上得到的资源位置和访问这些额资源的方法。
格式:://:/
?参数
3.HTTP
HyperText Transfer Protocol 超文本传输协议
HTTP:80 ---面向文本 HTTPS:443(加密)
定义了万维网客户端如何想万维网服务器请求万维网文档,以及服务器怎样把文档传给客户端。
(1).HTTP工作过程:
1)建立TCP连接
2)客户端向服务器发送HTTP请求报文
3)服务器向客户端发送HTTP响应报文
4)释放TCP连接
(2).HTTP报文格式
请求报文(从客户端向服务器发送请求报文):请求行、消息报头、请求正文
响应报文(从服务器到客户的回答):状态行、消息报头、响应正文
HTTP是面向文本的,因此在报文中的每一个字段都是一些ASCII码串,各个字段的长度都是不确定的
(3).请求方式
GET 请求获取Request-URI所标识的资源
POST 在Request-URI所标识的资源后附加新的数据
HEAD 请求获取由Request-URI所标识的资源的响应消息报头
PUT 请求服务器存储一个资源,并用Request-URI作为其标识
DELETE 请求服务器删除Request-URI所标识的资源
TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求
CONNECT 用于代理服务器
(4).状态码
1xx:指示信息--表示请求已接收,继续处理
2xx:成功--表示请求已被成功接收、理解、接受
3xx:重定向--要完成请求必须进行更进一步的操作
4xx:客户端错误--请求有语法错误或请求无法实现
5xx:服务器端错误--服务器未能实现合法的请求
200 OK //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
4.JSON格式
键值对的集合
(1)键值对 “关键字”:“字符串值”
(2)对象(集合) {}
(3)对象数组 []
5.函数接口
(1).char *strstr(const char *haystack, const char *needle);
功能:在源字符串中定位目标字符串
参数: haystack:源字符串首地址
needle:目标字符串首地址
返回值:成功:定位到的目标字符串的首地址 ; 失败:NULL
(2).char *index(const char *s, int c);
功能:在一个字符串中定位一个字符
参数:s:源字符串
c:需要定位的字符
返回值:成功:返回定位到字符的地址 ; 失败:NULL
响应标头
HTTP/1.1 200 OK Date: Wed, 23 Jul 2025 07:33:59 GMT Content-Type: text/html;charset=utf-8 Server: openresty Vary: Accept-Encoding Vary: Origin Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Trace-Id: 802100e5d5744cb6bba3fdf2ff8a6085.951.17532560398796951 Data-Source: X-Content-Type-Options: nosniff X-XSS-Protection: 0 S-REQ-ID: 159063873961547570 S-REQ-TYPE: 0 X-Cache-Lookup: Cache Miss Content-Encoding: gzip Cache-Control: no-cache Transfer-Encoding: chunked X-NWS-LOG-UUID: 159063873961547570 Connection: keep-alive X-Cache-Lookup: Cache Miss
请求标头
GET / HTTP/1.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 Cache-Control: max-age=0 Connection: keep-alive Cookie: SUV=1724151185440cesitz; gidinf=x099980109ee1956b7900e0080001b7b9f522cda0ff1; clt=1753254871; cld=20250723151431; reqtype=pc; _dfp=ZDmA0pQwxr24lgtMFaQG269FjIzJ0xyVW5vsDHNmhqo=; hideAddDesktop=true; t=1753255977242; beans_new_turn=%7B%22sohu-index%22%3A18%7D Host: news.sohu.com Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0
二、天气爬虫
#include #include #include #include \"cJSON.h\"#include \"head.h\"int init_tcp_cli(const char *ip, unsigned short port){ int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror(\"fail socket\"); return -1; } struct sockaddr_in seraddr; seraddr.sin_family = AF_INET; seraddr.sin_port = htons(port); seraddr.sin_addr.s_addr = inet_addr(ip); int ret = connect(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr)); if (ret < 0) { perror(\"fail connect\"); } return sockfd;}int send_http_request(int sockfd, char *buf, int n){ char vel[1024] = {0}; if (n == 1) { snprintf( vel, sizeof(vel), \"GET \" \"/?app=weather.today&cityNm=%s&appkey=76834&sign=\" \"475925eed5360335570b3bb0e264df65&format=json HTTP/1.1\\r\\n\" \"Host: api.k780.com\\r\\n\" \"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) \" \"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 \" \"Safari/537.36 Edg/138.0.0.0\\r\\n\" \"Accept: \" \"text/html,application/xhtml+xml,application/xml;q=0.9,image/\" \"avif,image/webp,image/apng,*/*;q=0.8,application/\" \"signed-exchange;v=b3;q=0.7\\r\\n\" \"Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6\\r\\n\" \"Connection: close\\r\\n\\r\\n\", buf); } else if (n == 2) { snprintf( vel, sizeof(vel), \"GET \" \"/?app=weather.future&cityNm=%s&&appkey=76834&sign=\" \"475925eed5360335570b3bb0e264df65&format=json HTTP/1.1\\r\\n\" \"Host: api.k780.com\\r\\n\" \"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) \" \"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 \" \"Safari/537.36 Edg/138.0.0.0\\r\\n\" \"Accept: \" \"text/html,application/xhtml+xml,application/xml;q=0.9,image/\" \"avif,image/webp,image/apng,*/*;q=0.8,application/\" \"signed-exchange;v=b3;q=0.7\\r\\n\" \"Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6\\r\\n\" \"Connection: close\\r\\n\\r\\n\", buf); } // printf(\"Sending request:\\n%s\\n\", vel); ssize_t size = send(sockfd, vel, strlen(vel), 0); if (size valuestring); if (type == 1) { printf(\"\\n=== 今日天气 ===\\n\"); // cJSON *item = cJSON_GetArrayItem(result,0); // printf(\"%s\\n\",(char *)item); if (result) { printf(\"城市: %s\\n\", cJSON_GetObjectItem(result, \"citynm\")->valuestring); printf(\"天气: %s\\n\", cJSON_GetObjectItem(result, \"weather\")->valuestring); printf(\"温度: %s°C\\n\", cJSON_GetObjectItem(result, \"temperature\")->valuestring); printf(\"湿度: %s%%\\n\", cJSON_GetObjectItem(result, \"humidity\")->valuestring); printf(\"风向: %s\\n\", cJSON_GetObjectItem(result, \"wind\")->valuestring); printf(\"风力: %s\\n\", cJSON_GetObjectItem(result, \"winp\")->valuestring); } } else { printf(\"\\n=== 未来天气预报 ===\\n\"); int i = 0; int n = cJSON_GetArraySize((const cJSON *)result); for (i = 0; i valuestring); printf(\"天气: %s\\n\", cJSON_GetObjectItem(item, \"weather\")->valuestring); printf(\"温度: %s°C ~ %s°C\\n\", cJSON_GetObjectItem(item, \"temp_low\")->valuestring, cJSON_GetObjectItem(item, \"temp_high\")->valuestring); printf(\"风向: %s\\n\", cJSON_GetObjectItem(item, \"wind\")->valuestring); printf(\"风力: %s\\n\", cJSON_GetObjectItem(item, \"winp\")->valuestring); } } cJSON_Delete(root);}int recv_http_response(int sockfd, int type){ char buf[4096] = {0}; char response[8192] = {0}; while (1) { memset(buf, 0, sizeof(buf)); ssize_t size = recv(sockfd, buf, sizeof(buf) - 1, 0); if (size < 0) { perror(\"fail recv\"); return -1; } else if (size == 0) { break; } strcat(response, buf); } // printf(\"%s\\n\",response); char *json_start = strstr(response, \"\\r\\n\\r\\n\"); while (*json_start != \'{\') { json_start++; // printf(\"%s\\n\",json_start); } parse_weather_json(json_start, type); // printf(\"%s\\n\",json_start); return 0;}void shuru(int sockfd){ char buf[1024] = {0}; int n = 0; while (1) { sockfd = init_tcp_cli(\"103.205.5.249\", 80); memset(buf, 0, sizeof(buf)); printf(\"请输入要查询天气的城市:\\n\"); fgets(buf, sizeof(buf), stdin); buf[strlen(buf) - 1] = \'\\0\'; if (0 == strncmp(buf, \"quit\", 4)) { break; } printf(\"请输入1或2,1对应该城市的当前天气,2对应该城市的未来天气\\n\"); scanf(\"%d\", &n); getchar(); send_http_request(sockfd, buf, n); recv_http_response(sockfd, n); close(sockfd); }}int main(int argc, char **argv){ int sockfd = init_tcp_cli(\"103.205.5.249\", 80); if (sockfd < 0) { return -1; } shuru(sockfd); close(sockfd); return 0;}
相关函数接口学习