打印
[其他ST产品]

STM32 W5500 HTTP Client POST 方式请求/提交网络数据

[复制链接]
785|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
现在想让STM32 W5500通过HTTP Client POST的方式提交数据到远程服务器,并接收服务返回的JSON格式数据,解析和处理。

实现以上功能,需要具备几个条件:

1、STM32 W5500的基础配置,使得PC和W5500在同一个局域网内,PC可以PING通W5500。

2、STM32 W5500的TCP Client可以成功发数据,HTTP协议是基于TCP协议之上封装的协议。

3、远程服务器接口可以访问,可以通过POSTMAN工具先测试。

4、使用WireShark工具,追踪POSTMAN访问服务接口的报文数据,以及返回的报文数据。

STM32 W5500的基础配置和TCP Client我已具备条件,下面看下远程服务器接口是否可以访问:


使用特权

评论回复
评论
突然下起雨 2023-1-15 17:22 回复TA
———————————————— 版权声明:本文为CSDN博主「Mr_Johhny」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/lnniyunlong99/article/details/105614408/ 
沙发
突然下起雨|  楼主 | 2023-1-15 17:24 | 只看该作者
Header部分:

使用特权

评论回复
板凳
突然下起雨|  楼主 | 2023-1-15 17:24 | 只看该作者
Request Body和Response Body

使用特权

评论回复
地板
突然下起雨|  楼主 | 2023-1-15 17:25 | 只看该作者
接口返回了JSON 结构数据,说明接口是可以访问的。

打开WireShark工具,追踪一下POSTMAN访问的流数据,以及服务器返回的响应报文数据。

使用特权

评论回复
5
突然下起雨|  楼主 | 2023-1-15 17:26 | 只看该作者
请求数据的追踪

使用特权

评论回复
6
突然下起雨|  楼主 | 2023-1-15 17:27 | 只看该作者
接口返回的报文数据追踪

使用特权

评论回复
7
突然下起雨|  楼主 | 2023-1-15 17:27 | 只看该作者

使用特权

评论回复
8
突然下起雨|  楼主 | 2023-1-15 17:28 | 只看该作者
基础准备工作已经做好,那么STM32 W5500 Http Client POST请求的实现,由于一些信息比较敏感,对代码做了处理:

使用特权

评论回复
9
突然下起雨|  楼主 | 2023-1-15 17:29 | 只看该作者
httppost.c
#ifndef __HTTPPOST_H
#define __HTTPPOST_H
#include "httppost.h"
#endif

u16 func_pack_httppost_body(char *buff_body, char *productId, char *deviceSn, char *deviceMac, char *devicePassword, char *hardwareVersion)
{
        u16 len;
        len = sprintf(buff_body, "a=%s&b=%s&c=%s&d=%s&e=%s",\
                productId, deviceSn, deviceMac, devicePassword, hardwareVersion);
        return len;
}

u16 func_pack_httppost_head_body(char *buff_post, char *url_tail, u8 *host, u16 port, char *body, u16 body_len)
{
        u16 len;
        len = sprintf(buff_post, "POST %s HTTP/1.1\r\n"
                "Connection: close\r\n"
                "User-Agent:W5500\r\n"
                "Content-Type:application/x-www-form-urlencoded\r\n"
                "Host: %d.%d.%d.%d:%d\r\n"
                "Content-Length: %d\r\n\r\n"
                "%s\r\n", url_tail, host[0], host[1], host[2], host[3], port, body_len, body
        );
        return len;
}

static u16 local_port = 50000;

u8 func_http_post(u8 sock_no, u8 *rip, u16 port, char *buf_post, u16 len_post,char *buf_recv, u16 *len_recv, u16 timeout_ms)
{
        u16 cnt, len;       
        char *body_cont;
        cnt = 0;
       
        for(;;)
        {
                switch(getSn_SR(sock_no))
                {
                        case SOCK_INIT:
                                connect(sock_no, rip, port);
                        break;
                        case SOCK_ESTABLISHED:
                                send(sock_no, (u8*)buf_post, len_post);
                                if(getSn_IR(sock_no) & Sn_IR_CON)                                          
                                {
                                        setSn_IR(sock_no, Sn_IR_CON);
                                }
                                len = getSn_RX_RSR(sock_no);
                                if(len > 0)
                                {
                                        memset(buf_recv, 0, len_post);
                                        len = recv(sock_no, (u8*)buf_recv, len);
                                        body_cont = strstr((char*)buf_recv, "HTTP/1.1 200");
                                        if(body_cont == NULL)
                                        {
                                                return 2;
                                        }
                                        body_cont = strstr((char*)buf_recv, "\r\n\r\n");
                                        if(body_cont != NULL)
                                        {
                                                len = strlen(body_cont) - 4;
                                                memcpy(buf_recv, body_cont + 4, len);
                                                buf_recv[len] = '\0';
                                                *len_recv = len;
                                                close(sock_no);
                                                return 0;
                                        }                                       
                                }                               
                        break;
                        case SOCK_CLOSE_WAIT:
                                close(sock_no);
                        break;
                        case SOCK_CLOSED:
                                socket(sock_no, Sn_MR_TCP, local_port++, Sn_MR_ND);
                                if(local_port > 64000)
                                {
                                        local_port = 50000;
                                }
                        break;
                }
               
                cnt ++;
                if(cnt >= timeout_ms)
                {
                        close(sock_no);
                        return 1;
                }
                delay_ms(1);
        }
}

使用特权

评论回复
10
突然下起雨|  楼主 | 2023-1-15 17:29 | 只看该作者
测试的主函数代码:
#ifndef __STM32F10X_H
#define __STM32F10X_H
#include "stm32f10x.h"
#endif

#ifndef __Z_UTIL_TIME_H
#define __Z_UTIL_TIME_H
#include "z_util_time.h"
#endif

#ifndef __Z_HARDWARE_LED_H
#define __Z_HARDWARE_LED_H
#include "z_hardware_led.h"
#endif

#ifndef __Z_HARDWARE_SPI_H
#define __Z_HARDWARE_SPI_H
#include "z_hardware_spi.h"
#endif

#ifndef __Z_HARDWARE_USART2_H
#define __Z_HARDWARE_USART2_H
#include "z_hardware_usart2.h"
#endif

#include "w5500.h"
#include "socket.h"
#include "w5500_conf.h"
#include "dhcp.h"
#include "dns.h"

#ifndef __HTTPPOST_H
#define __HTTPPOST_H
#include "httppost.h"
#endif

char buf_send[2048];
char buf_cont[256];
       
int main(void)
{
        DHCP_Get dhcp_get;
//        u8 buf_recv[1536] = {0, };
       
        u16 len, recv_len;
        u8 res;
       
        uint8 mac[6];
        u8 remote_ip[4] = {192, 168, 1, 109};
        u16 port = 8084;       
       
        init_led();
       
        init_system_spi();
        func_w5500_reset();
       
        init_hardware_usart2_dma(115200);
               
        getMacByLockCode(mac);
        setSHAR(mac);
       
        sysinit(txsize, rxsize);
        setRTR(2000);
  setRCR(3);
       
        //USART DMA problem 2byte missing
        func_usart2_dma_send_bytes(mac, 2);
        delay_ms(100);
       
        //DHCP
        for(;func_dhcp_get_ip_sub_gw(1, mac, &dhcp_get, 500) != 0;);       
        if(func_dhcp_get_ip_sub_gw(1, mac, &dhcp_get, 500) == 0)
        {
                setSUBR(dhcp_get.sub);
                setGAR(dhcp_get.gw);
                setSIPR(dhcp_get.lip);
        }
       
        len = func_pack_httppost_body(buf_cont, "", "", "", "", "");
       
//        pack http message               
        len = func_pack_httppost_head_body(buf_send, "/a/b/c/d/create", remote_ip, port, buf_cont, len);
       
//        res = func_httpc_post(0, remote_ip, port, buf_send, len, buf_send, &recv_len, 1000, 5000);
        res = func_http_post(0, remote_ip, port, buf_send, len, buf_send, &recv_len, 1000);
        if(res == 0)
        {
                func_usart2_dma_send_bytes((u8*)buf_send, recv_len);
        }

        for(;;)
        {
               
                func_led1_on();
                delay_ms(1000);
                func_led1_off();
                delay_ms(1000);
               
        }
}

使用特权

评论回复
11
突然下起雨|  楼主 | 2023-1-15 17:35 | 只看该作者
测试的结果,解析报文的body,并通过串口打印出来:

使用特权

评论回复
12
突然下起雨|  楼主 | 2023-1-15 17:36 | 只看该作者
通过16进制转字符串转换一下,看看结果

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

38

主题

284

帖子

1

粉丝