HTTPCLIENT源码分析

HTTPCLIENT源码分析

—mt7686 httpclient模块

http是应用层的协议,在传输层使用tcp协议,可以从其源码分析,中间层就是调用socket(基于lwip协议)编程加上http协议实现,下面看源码。想看看其源码的可以从下面目录下载。
下载目录:点击这里
路径在middleware/third_party/httpclient中。

源码分析
以前已经介绍过httpclient api的使用了,此处不在赘述,本文主要介绍下面代码的中间层实现。

static HTTPCLIENT_RESULT httpclient_common(httpclient_t *client, char *url, int method, httpclient_data_t *client_data)
{
    HTTPCLIENT_RESULT ret = HTTPCLIENT_ERROR_CONN;

    ret = httpclient_connect(client, url);

    if (!ret) {
        ret = httpclient_send_request(client, url, method, client_data);

        if (!ret) {
            ret = httpclient_recv_response(client, client_data);
        }
    }

    httpclient_close(client);

    return ret;
}

1.httpclient_connect函数

创建tcp连接过程,此处贴出主要代码。

	//解析url,确认目的地址
	httpclient_parse_url(url, scheme, sizeof(scheme), host, sizeof(host), &(client->remote_port), path, HTTPCLIENT_MAX_URL_LEN);
	//检查http or https后,确认端口
 	   if (client->remote_port == 0) {
   	     if (client->is_http) {
      	      client->remote_port = HTTP_PORT;
    	    } else {
    	        client->remote_port = HTTPS_PORT;
   	     }
  	  }
     //以tcp,创建tcp连接
        if (client->is_http)
    	    ret = httpclient_conn(client, host);
     //分析httpclient_conn;创建套接字,填充地址结构,连接
     //填充地址结构
 	   memset( &hints, 0, sizeof( hints ) );
 	   hints.ai_family = AF_UNSPEC;
  	  hints.ai_socktype = SOCK_STREAM;
  	  hints.ai_protocol = IPPROTO_TCP;
	  snprintf(port, sizeof(port), "%d", client->remote_port) ;
  	  if ( getaddrinfo( host, port , &hints, &addr_list ) != 0 ) {
     	   DBG("getaddrinfo != 0, return HTTPCLIENT_UNRESOLVED_DNS");
      	  return HTTPCLIENT_UNRESOLVED_DNS;
  	  }
     //创建套接字
        client->socket = (int) socket( cur->ai_family, cur->ai_socktype,
                                        cur->ai_protocol );
	 //连接
		connect( client->socket, cur->ai_addr, (int)cur->ai_addrlen )

至此,函数如果正确返回,就创建tcp连接成功了,接下来就是发送接收数据了,最终应该调用的send(),recv()函数接口。

2.httpclient_send_request函数

了解这个函数接口,必须了解下http报文结构了,这里以请求报文为例。
在这里插入图片描述
发送http数据之前,都会先发送报文首部数据,然后再看这个函数实现。

HTTPCLIENT_RESULT httpclient_send_request(httpclient_t *client, char *url, int method, httpclient_data_t *client_data)
{
    int ret = HTTPCLIENT_ERROR_CONN;

    if (client->socket < 0) {
        return (HTTPCLIENT_RESULT)ret;
    }
//发送报文首部
    ret = httpclient_send_header(client, url, method, client_data);
    if (ret != 0) {
        return (HTTPCLIENT_RESULT)ret;
    }

    if (method == HTTPCLIENT_POST || method == HTTPCLIENT_PUT) {
    //发送用户数据
        ret = httpclient_send_userdata(client, client_data);  
    }

    DBG("httpclient_send_request() result:%d, client:%p", ret, client);
    return (HTTPCLIENT_RESULT)ret;
}

HTTP 首部字段是构成 HTTP 报文的要素之一。在客户端与服务器之
间以 HTTP 协议进行通信的过程中,无论是请求还是响应都会使用首
部字段,它能起到传递额外重要信息的作用。代码实现不做解释了。

注意:关于这个api,想发送数据,跟到函数最后肯定调用lwip协议栈中send函数。
如下,httpclient最终只要发送数据都会调用下面接口

 send(sock_fd, data + written_len, length - written_len, 0);

3.httpclient_recv_response函数

接收http响应的函数接口,同理,接收的也是一个响应报文,除了接收数据后,对接收的报文也需要解析,这就是这个函数的具体功能了。
响应报文如下:
在这里插入图片描述
接收数据:

httpclient_recv(client, data + len, 1, header_buf_len - len - 1, &new_trf_len);

最终调用lwip协议栈中的接口recv

recv(client->socket, buf + readLen, max_len - readLen, 0);

关于http请求与响应的报文首部,想详细了解和学习的,可以取查阅《图解http》。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值