webclient学习4.webclient-流程分析

1.使用流程

使用 WebClient 软件包发送 GET/POST 请求一般需要完成如下基本流程:

(1) 创建客户端会话结构体

struct  webclient_header
{
    char *buffer;                       //添加或者获取的头部数据
    size_t length;                      //存放当前头部数据长度

    size_t size;                        //存放最大支持的头部数据长度
};

struct webclient_session
{
    struct webclient_header *header;    //保存头部信息结构体
    int socket;                         //当前连接套接字
    int resp_status;                    //响应状态码

    char *host;                         //连接服务器地址
    char *req_url;                      //连接的请求地址

    int chunk_sz;                       //chunk 模式下一块数据大小
    int chunk_offset;                   //chunk 模式剩余数据大小

    int content_length;                 //当前接收数据长度(非 chunk 模式)
    size_t content_remainder;           //当前剩余接收数据长度
    
    rt_bool_t is_tls;                   //当前连接是否是 HTTPS 连接
#ifdef WEBCLIENT_USING_MBED_TLS
    MbedTLSSession *tls_session;        // HTTPS 协议相关会话结构体
#endif
};

webclient_session 结构体用于存放当前建立的 HTTP 连接的部分信息,可用与 HTTP 数据交互整个流程。建立 HTTP 连接前需要创建并初始化该结构体,创建的方式示例如下:

struct webclient_session *session = RT_NULL;

/* create webclient session and set header response size */
session = webclient_session_create(1024);
if (session == RT_NULL)
{
    ret = -RT_ENOMEM;
    goto __exit;
}

(2) 拼接头部数据

WebClient 软件包提供两种请求头部发送方式:

  • 默认头部数据

    如果要使用默认的头部信息,则不需要拼接任何头部数据,可直接调用 GET 发送命令。默认头部数据一般只用于 GET 请求。

  • 自定义头部数据

自定义头部数据使用 webclient_header_fields_add 函数添加头部信息,添加的头部信息位于客户端会话结构体中,在发送 GET/POST 请求时发送。

添加示例代码如下:

/* 拼接头部信息 */
webclient_header_fields_add(session, "Content-Length: %d\r\n", strlen(post_data));

webclient_header_fields_add(session, "Content-Type: application/octet-stream\r\n");

(3) 发送 GET/POST 请求

头部信息添加完成之后,就可以调用 webclient_get 函数或者 webclient_post 函数发送 GET/POST 请求命令了,函数中主要操作如下:

  • 通过传入的 URI 获取信息,建立 TCP 连接;
  • 发送默认或者拼接的头部信息;
  • 接收并解析响应数据的头部信息;
  • 返回错误或者响应状态码。

发送 GET 请求示例代码如下:

int resp_status = 0;

/* send GET request by default header */
if ((resp_status = webclient_get(session, URI)) != 200)
{
    LOG_E("webclient GET request failed, response(%d) error.", resp_status);
    ret = -RT_ERROR;
    goto __exit;
}

(4) 接收响应的数据

发送 GET/POST 请求之后,可以使用 webclient_read 函数接收响应的实际数据。因为响应的实际数据可能比较长,所以往往我们需要循环接收响应数据,指导数据接收完毕。

如下所示为循环接收并打印响应数据方式:

int content_pos = 0;
/* 获取接收的响应数据长度 */
int content_length = webclient_content_length_get(session);

/* 循环接收响应数据直到数据接收完毕 */
do
{
    bytes_read = webclient_read(session, buffer, 1024);
    if (bytes_read <= 0)
    {
        break;
    }

    /* 打印响应数据 */
    for (index = 0; index < bytes_read; index++)
    {
        rt_kprintf("%c", buffer[index]);
    }

    content_pos += bytes_read;
} while (content_pos < content_length);

(5) 关闭并释放客户端会话结构体

请求发送并接收完成之后,需要使用 webclient_close 函数关闭并释放客户端会话结构体,完成整个 HTTP 数据交互流程。

使用方式如下:

if (session)
{
    webclient_close(session);
}

2.使用方式

WenClient 软件包对于 GET/POST 请求,分别提供了几种不同的使用方式,用于不同的情况。

GET 请求方式

  • 使用默认头部发送 GET 请求
struct webclient_session *session = NULL;

session = webclient_create(1024);

if(webclient_get(session, URI) != 200)
{
    LOG_E("error!");
}

while(1)
{
    webclient_read(session, buffer, bfsz);
    ...
} 

webclient_close(session);
  • 使用自定义头部发送 GET 请求
struct webclient_session *session = NULL;

session = webclient_create(1024);

webclient_header_fields_add(session, "User-Agent: RT-Thread HTTP Agent\r\n");

if(webclient_get(session, URI) != 200)
{
    LOG_E("error!");
}

while(1)
{
    webclient_read(session, buffer, bfsz);
    ...
} 

webclient_close(session);
  • 发送获取部分数据的 GET 请求(多用于断点续传)
struct webclient_session *session = NULL;

session = webclient_create(1024);

if(webclient_get_position(URI, 100) != 206)
{
    LOG_E("error!");
}

while(1)
{
    webclient_read(session, buffer, bfsz);
    ...
} 

webclient_close(session)
  • 使用 webclient_response 接收 GET 数据

    多用于接收数据长度较小的 GET 请求。

struct webclient_session *session = NULL;
size_t length = 0;
char *result;

session = webclient_create(1024);

if(webclient_get(session, URI) != 200)
{
    LOG_E("error!");
}

webclient_response(session, &result, &length);

web_free(result);
webclient_close(session);
  • 使用 webclient_request 函数发送并接收 GET 请求

    多用于接收数据长度较小,且头部信息已经拼接给出的 GET 请求。

size_t length = 0;
char *result, *header = RT_NULL;

/* 拼接自定义头部数据 */
webclient_request_header_add(&header, "User-Agent: RT-Thread HTTP Agent\r\n");

webclient_request(URI, header, NULL, 0, &result, &length);

web_free(result);

POST 请求方式

  • 分段数据 POST 请求

    多用于上传数据量较大的 POST 请求,如:上传文件到服务器。

struct webclient_session *session = NULL;

session = webclient_create(1024);

/*  拼接必要的头部信息 */
webclient_header_fields_add(session, "Content-Length: %d\r\n", post_data_sz);
webclient_header_fields_add(session, "Content-Type: application/octet-stream\r\n");

/* 分段数据上传 webclient_post 第三个传输上传数据为 NULL,改为下面循环上传数据*/
if( webclient_post(session, URI, NULL, 0) != 200)
{
    LOG_E("error!");
}

while(1)
{
    webclient_write(session, post_data, 1024);
    ...
} 

if( webclient_handle_response(session) != 200)
{
    LOG_E("error!");
}

webclient_close(session);
  • 整段数据 POST 请求

    多用于上传数据量较小的 POST 请求。

char *post_data = "abcdefg";

session = webclient_create(1024);

/*  拼接必要的头部信息 */
webclient_header_fields_add(session, "Content-Length: %d\r\n", strlen(post_data));
webclient_header_fields_add(session, "Content-Type: application/octet-stream\r\n");

if(webclient_post(session, URI, post_data, rt_strlen(post_data)) != 200);
{
    LOG_E("error!");
}
webclient_close(session);
  • 使用 webclient_request 函数发送 POST 请求

    多用于上传文件较小且头头部信息已经拼接给出的 POST 请求。

char *post_data = "abcdefg";
char *header = RT_NULL;

/* 拼接自定义头部数据 */
webclient_request_header_add(&header, "Content-Length: %d\r\n", strlen(post_data));
webclient_request_header_add(&header, "Content-Type: application/octet-stream\r\n");

webclient_request(URI, header, post_data, rt_strlen(post_data), NULL, NULL);
  • 原因:添加的头部数据长度超过了最大支持的头部数据长度。
  • 解决方法:在创建客户端会话结构体的时候,增大传入的最大支持的头部数据长度。

3.http协议头部分析

HTTP请求头部信息:

请求行 :请求方式 请求url HTTP协议版本
请求头部 :键值对(类型,长度...)
空行
请求数据

在这里插入图片描述
HTTP响应头部信息:

状态行:协议版本 状态码 状态
消息报头:键值对(类型,长度...)
空行
响应数据

在这里插入图片描述

4.常见问题

HTTPS 地址不支持

[E/WEB]not support https connect, please enable webclient https configure!
  • 原因:使用 HTTPS 地址但是没有开启 HTTPS 支持。
  • 解决方法:在 WebClient 软件包 menuconfig 配置选项中 选择 Select TLS mode 选项为 MbedTLS support 或者 SAL TLS support

头部数据长度超出

[E/WEB]not enough header buffer size(xxx)!
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值