实用小技巧 | 用socket玩转http接口

Posted Mculover666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实用小技巧 | 用socket玩转http接口相关的知识,希望对你有一定的参考价值。

一、前言

曾几何时,HTTP这种应用层协议对于我来说有点高级,总觉得调用 HTTP 接口是一件很难实现的事情,需要用一个很牛逼的库才行。

直到昨天我学习了一个骚操作,原来用 socket 就可以直接玩 http,赶紧分享一波~

开门见山,用socket玩转http接口就四步:

  • ① 建立 tcp 链接;
  • ② 发送请求数据(请求报文);
  • ③ 接收响应数据(响应报文);
  • ④ 关闭 tcp链接,从接收数据中提取有效信息。

接下来一步一步开始玩。

二、请求报文和响应报文

1. 发送什么

建立 TCP 之后,要向服务器发送请求报文。请求报文的格式非常重要,稍微偏差服务器就不认,返回一堆其它的东西,比如错误码,404 not found等。

HTTP请求报文的格式如图:

(图片来源于网络)

主要包括四部分:

  • 请求行:由请求方法(GET或者POST)、URI(注意不是URL)、HTTP协议版本(HTTP/1.1)组成,中间使用空格分离,末尾换行;
  • 请求头部:一些字段及其值,每个字段占一行;
  • 空行:表示请求报文结束;
  • 请求体:POST方法时需要,GET方法时不需要。

2. 接收什么

HTTP 服务器收到请求报文后,会返回对应的结果,称之为响应报文:实用小技巧 | 用socket玩转http接口

(图片来源于网络)

在嵌入式设备中通常是从返回结果中提取有效信息,并且大多数API接口返回都是json数据格式,所以不用过于关心响应报文。

话不多说,直接开干!

三、用网络调试助手测试

1. 测试文件

http://www.mculover666.cn/hello.txt

使用浏览器访问结果如图:实用小技巧 | 用socket玩转http接口

2.2. 建立TCP链接

2.3. 发送请求报文

根据第二节的请求报文格式+要请求的URL,组装出要发送的内容如下:

GET /hello.txt HTTP/1.1
HOST:www.mculover666.cn


2.4. 处理请求报文

发出请求报文之后,服务器收到后返回的响应报文如下:

HTTP/1.1 200 OK
Server: nginx
Date: Sun, 20 Sep 2020 11:30:32 GMT
Content-Type: text/plain
Content-Length: 44
Last-Modified: Sat, 19 Sep 2020 14:26:02 GMT
Connection: keep-alive
ETag: "5f6614fa-2c"
Accept-Ranges: bytes

you get success! nb! say from mculover666! 

至于怎么对收到的数据进行解析,这就要秀出你的字符串解析功底了,比如strstr、sscanf、使用FIFO缓冲之后解析等骚操作。

好在物联网设备中大部分时候都是返回JSON内容或者文件内容。

四、使用TencentOS-tiny对接

常用的物联网操作系统都提供了基本的 TCP socket通信功能,这里我使用 TencentOS-tiny + ESP8266进行测试。

测试前请保证socket可以正常通信。

编写如下应用代码:

void application_entry(void *arg)
{
    int ret = -1;
    int socket_id = -1;
    
    esp8266_sal_init(HAL_UART_PORT_0);
    esp8266_join_ap("Tencent-WIFI""424424424");

    /* start connect */
    socket_id = tos_sal_module_connect("122.51.89.94""80", TOS_SAL_PROTO_TCP); 
    if (socket_id == -1) {
        printf("TCP0 connect failed\r\n");
    } else {
        printf("TCP0 connect success! fd: %d\n", socket_id);
    }
    
    /* send request */
    ret = tos_sal_module_send(socket_id, (const void*)REQUEST_DATA, strlen(REQUEST_DATA));
    if (ret < 0) {
        printf("send fail\r\n");
    } else {
        printf("send success, %d bytes\r\n", ret);
    }
    
    /* recv response */
    ret = tos_sal_module_recv_timeout(socket_id, recv_data_buf, sizeof(recv_data_buf), 8000);
    if (ret < 0) {
        printf("task1 receive error\n\r");
    } else if (ret == 0) {
        printf("task1 receive none\n");
    } else {
        recv_data_buf[ret] = 0;
        printf("task1: receive len: %d\nmsg from remote: %s\n", ret, recv_data_buf);
    }
    
    /* close socket */
    tos_sal_module_close(socket_id);

}

编译,下载到开发板中,在串口助手中查看结果:

怎么样,HTTP玩起来是不是很简单?

本文只是提供一种行之有效的思路,请求报文中的字段还有很多,需要查阅类似HTTP协议详解的文章去探索、测试,这里不做过多讲解。

感兴趣的读者可以再找点API接口玩玩哈哈~学业繁忙,告辞!


以上是关于实用小技巧 | 用socket玩转http接口的主要内容,如果未能解决你的问题,请参考以下文章

轻松玩转163vip邮箱,分享163vip邮箱实用技巧

Flutter 小技巧之玩转字体渲染和问题修复

玩转EXCEL系列-选择性粘贴几个实用技巧

iPhone玩转safari浏览器的实用技巧

Markdown实用小技巧: 个个用着都很爽

最火Python3 玩转实用小工具