添加httpServer示例
This commit is contained in:
parent
918c03cd45
commit
3b113125ee
43
Core/Inc/http_server.h
Normal file
43
Core/Inc/http_server.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef __HTTP_SERVER_H
|
||||
#define __HTTP_SERVER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "socket.h"
|
||||
#include "w5500_init.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define HTTP_SERVER_PORT 80
|
||||
#define HTTP_SERVER_SOCKET 1
|
||||
#define MAX_URI_SIZE 128
|
||||
|
||||
// HTTP请求方法
|
||||
typedef enum {
|
||||
HTTP_GET,
|
||||
HTTP_POST,
|
||||
HTTP_UNKNOWN
|
||||
} http_method;
|
||||
|
||||
// HTTP请求结构
|
||||
typedef struct {
|
||||
http_method method;
|
||||
char uri[MAX_URI_SIZE];
|
||||
uint8_t* body;
|
||||
uint16_t body_length;
|
||||
} http_request;
|
||||
|
||||
// 初始化HTTP服务器
|
||||
void http_server_init(void);
|
||||
|
||||
// 处理HTTP服务器任务
|
||||
void http_server_task(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HTTP_SERVER_H */
|
246
Core/Src/http_server.c
Normal file
246
Core/Src/http_server.c
Normal file
@ -0,0 +1,246 @@
|
||||
#include "http_server.h"
|
||||
|
||||
// HTML页面模板
|
||||
const char* html_page = "<!DOCTYPE html>"
|
||||
"<html><head>"
|
||||
"<title>W5500 Configuration</title>"
|
||||
"<style>"
|
||||
" body {"
|
||||
" font-family: Arial, sans-serif;"
|
||||
" max-width: 800px;"
|
||||
" margin: 20px auto;"
|
||||
" padding: 20px;"
|
||||
" background-color: #f5f5f5;"
|
||||
" }"
|
||||
" h2 {"
|
||||
" color: #333;"
|
||||
" text-align: center;"
|
||||
" padding-bottom: 10px;"
|
||||
" border-bottom: 2px solid #ddd;"
|
||||
" }"
|
||||
" form {"
|
||||
" background: white;"
|
||||
" padding: 20px;"
|
||||
" border-radius: 8px;"
|
||||
" box-shadow: 0 2px 4px rgba(0,0,0,0.1);"
|
||||
" }"
|
||||
" .form-group {"
|
||||
" margin-bottom: 15px;"
|
||||
" }"
|
||||
" label {"
|
||||
" display: inline-block;"
|
||||
" width: 80px;"
|
||||
" font-weight: bold;"
|
||||
" color: #555;"
|
||||
" }"
|
||||
" input[type='text'] {"
|
||||
" width: 200px;"
|
||||
" padding: 8px;"
|
||||
" border: 1px solid #ddd;"
|
||||
" border-radius: 4px;"
|
||||
" font-family: monospace;"
|
||||
" }"
|
||||
" input[type='submit'] {"
|
||||
" background-color: #4CAF50;"
|
||||
" color: white;"
|
||||
" padding: 10px 20px;"
|
||||
" border: none;"
|
||||
" border-radius: 4px;"
|
||||
" cursor: pointer;"
|
||||
" font-size: 16px;"
|
||||
" margin-top: 10px;"
|
||||
" }"
|
||||
" input[type='submit']:hover {"
|
||||
" background-color: #45a049;"
|
||||
" }"
|
||||
" .status {"
|
||||
" margin-top: 20px;"
|
||||
" padding: 10px;"
|
||||
" border-radius: 4px;"
|
||||
" text-align: center;"
|
||||
" }"
|
||||
" .connected {"
|
||||
" background-color: #dff0d8;"
|
||||
" color: #3c763d;"
|
||||
" border: 1px solid #d6e9c6;"
|
||||
" }"
|
||||
" .disconnected {"
|
||||
" background-color: #f2dede;"
|
||||
" color: #a94442;"
|
||||
" border: 1px solid #ebccd1;"
|
||||
" }"
|
||||
"</style>"
|
||||
"</head><body>"
|
||||
"<h2>W5500 Network Configuration</h2>"
|
||||
"<form method='post' action='/config'>"
|
||||
" <div class='form-group'>"
|
||||
" <label>MAC:</label>"
|
||||
" <input type='text' name='mac' value='%02X:%02X:%02X:%02X:%02X:%02X'>"
|
||||
" </div>"
|
||||
" <div class='form-group'>"
|
||||
" <label>IP:</label>"
|
||||
" <input type='text' name='ip' value='%d.%d.%d.%d'>"
|
||||
" </div>"
|
||||
" <div class='form-group'>"
|
||||
" <label>Subnet:</label>"
|
||||
" <input type='text' name='subnet' value='%d.%d.%d.%d'>"
|
||||
" </div>"
|
||||
" <div class='form-group'>"
|
||||
" <label>Gateway:</label>"
|
||||
" <input type='text' name='gateway' value='%d.%d.%d.%d'>"
|
||||
" </div>"
|
||||
" <input type='submit' value='Save Configuration'>"
|
||||
"</form>"
|
||||
"<div class='status %s'>"
|
||||
" Network Status: %s"
|
||||
"</div>"
|
||||
"</body></html>";
|
||||
|
||||
// 解析HTTP请求
|
||||
static void parse_http_request(uint8_t* buffer, uint16_t length, http_request* req)
|
||||
{
|
||||
char* method = strtok((char*)buffer, " ");
|
||||
char* uri = strtok(NULL, " ");
|
||||
|
||||
if(strcmp(method, "GET") == 0) {
|
||||
req->method = HTTP_GET;
|
||||
} else if(strcmp(method, "POST") == 0) {
|
||||
req->method = HTTP_POST;
|
||||
} else {
|
||||
req->method = HTTP_UNKNOWN;
|
||||
}
|
||||
|
||||
strncpy(req->uri, uri, MAX_URI_SIZE);
|
||||
|
||||
// 如果是POST请求,查找请求体
|
||||
if(req->method == HTTP_POST) {
|
||||
char* body = strstr((char*)buffer, "\r\n\r\n");
|
||||
if(body) {
|
||||
body += 4;
|
||||
req->body = (uint8_t*)body;
|
||||
req->body_length = length - (body - (char*)buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 发送HTTP响应
|
||||
static void send_response(uint8_t sn, const char* content, uint16_t length)
|
||||
{
|
||||
char header[128];
|
||||
sprintf(header,
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: text/html\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"\r\n", length);
|
||||
|
||||
send(sn, (uint8_t*)header, strlen(header));
|
||||
send(sn, (uint8_t*)content, length);
|
||||
}
|
||||
|
||||
// 处理配置页面请求
|
||||
static void handle_config_page(uint8_t sn)
|
||||
{
|
||||
char page[4096]; // 增加缓冲区大小以适应新的HTML内容
|
||||
bool is_connected = (wizphy_getphylink() == PHY_LINK_ON);
|
||||
char* link_status = is_connected ? "Connected" : "Disconnected";
|
||||
char* status_class = is_connected ? "connected" : "disconnected";
|
||||
|
||||
sprintf(page, html_page,
|
||||
gWIZNETINFO.mac[0], gWIZNETINFO.mac[1], gWIZNETINFO.mac[2],
|
||||
gWIZNETINFO.mac[3], gWIZNETINFO.mac[4], gWIZNETINFO.mac[5],
|
||||
gWIZNETINFO.ip[0], gWIZNETINFO.ip[1], gWIZNETINFO.ip[2], gWIZNETINFO.ip[3],
|
||||
gWIZNETINFO.sn[0], gWIZNETINFO.sn[1], gWIZNETINFO.sn[2], gWIZNETINFO.sn[3],
|
||||
gWIZNETINFO.gw[0], gWIZNETINFO.gw[1], gWIZNETINFO.gw[2], gWIZNETINFO.gw[3],
|
||||
status_class, link_status);
|
||||
|
||||
send_response(sn, page, strlen(page));
|
||||
}
|
||||
|
||||
// 解析并更新网络配置
|
||||
static void update_network_config(const char* body)
|
||||
{
|
||||
char mac[18], ip[16], subnet[16], gateway[16];
|
||||
uint32_t mac_values[6], ip_values[4], subnet_values[4], gateway_values[4];
|
||||
|
||||
if(sscanf(body, "mac=%02X%%3A%02X%%3A%02X%%3A%02X%%3A%02X%%3A%02X&"
|
||||
"ip=%d.%d.%d.%d&"
|
||||
"subnet=%d.%d.%d.%d&"
|
||||
"gateway=%d.%d.%d.%d",
|
||||
&mac_values[0], &mac_values[1], &mac_values[2],
|
||||
&mac_values[3], &mac_values[4], &mac_values[5],
|
||||
&ip_values[0], &ip_values[1], &ip_values[2], &ip_values[3],
|
||||
&subnet_values[0], &subnet_values[1], &subnet_values[2], &subnet_values[3],
|
||||
&gateway_values[0], &gateway_values[1], &gateway_values[2], &gateway_values[3]) == 18)
|
||||
{
|
||||
// 更新MAC地址
|
||||
for(int i = 0; i < 6; i++) {
|
||||
gWIZNETINFO.mac[i] = (uint8_t)mac_values[i];
|
||||
}
|
||||
|
||||
// 更新IP地址
|
||||
for(int i = 0; i < 4; i++) {
|
||||
gWIZNETINFO.ip[i] = (uint8_t)ip_values[i];
|
||||
gWIZNETINFO.sn[i] = (uint8_t)subnet_values[i];
|
||||
gWIZNETINFO.gw[i] = (uint8_t)gateway_values[i];
|
||||
}
|
||||
|
||||
// 应用新的网络配置
|
||||
wizchip_setnetinfo(&gWIZNETINFO);
|
||||
}
|
||||
}
|
||||
|
||||
void http_server_init(void)
|
||||
{
|
||||
// 创建服务器socket
|
||||
socket(HTTP_SERVER_SOCKET, Sn_MR_TCP, HTTP_SERVER_PORT, 0);
|
||||
listen(HTTP_SERVER_SOCKET);
|
||||
}
|
||||
|
||||
void http_server_task(void)
|
||||
{
|
||||
uint8_t buffer[2048];
|
||||
uint16_t size;
|
||||
uint8_t status = getSn_SR(HTTP_SERVER_SOCKET);
|
||||
|
||||
switch(status)
|
||||
{
|
||||
case SOCK_LISTEN:
|
||||
// 等待连接
|
||||
break;
|
||||
|
||||
case SOCK_ESTABLISHED:
|
||||
{
|
||||
// 接收数据
|
||||
if((size = getSn_RX_RSR(HTTP_SERVER_SOCKET)) > 0)
|
||||
{
|
||||
size = recv(HTTP_SERVER_SOCKET, buffer, sizeof(buffer));
|
||||
if(size > 0)
|
||||
{
|
||||
http_request req;
|
||||
parse_http_request(buffer, size, &req);
|
||||
|
||||
if(req.method == HTTP_GET) {
|
||||
handle_config_page(HTTP_SERVER_SOCKET);
|
||||
}
|
||||
else if(req.method == HTTP_POST && strcmp(req.uri, "/config") == 0) {
|
||||
update_network_config((char*)req.body);
|
||||
// 重定向回配置页面
|
||||
send_response(HTTP_SERVER_SOCKET,
|
||||
"<html><head><meta http-equiv='refresh' content='0;url=/'></head></html>",
|
||||
strlen("<html><head><meta http-equiv='refresh' content='0;url=/'></head></html>"));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SOCK_CLOSE_WAIT:
|
||||
disconnect(HTTP_SERVER_SOCKET);
|
||||
break;
|
||||
|
||||
case SOCK_CLOSED:
|
||||
socket(HTTP_SERVER_SOCKET, Sn_MR_TCP, HTTP_SERVER_PORT, 0);
|
||||
listen(HTTP_SERVER_SOCKET);
|
||||
break;
|
||||
}
|
||||
}
|
@ -26,7 +26,8 @@
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "w5500_init.h"
|
||||
#include "http_test.h"
|
||||
#include "http_client.h"
|
||||
#include "http_server.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@ -103,7 +104,10 @@ int main(void)
|
||||
}
|
||||
}
|
||||
|
||||
// 执行HTTP测试
|
||||
// 初始化HTTP服务器
|
||||
http_server_init();
|
||||
|
||||
// 执行一次HTTP客户端测试
|
||||
http_test_request();
|
||||
/* USER CODE END 2 */
|
||||
|
||||
@ -114,6 +118,7 @@ int main(void)
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
http_server_task();
|
||||
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
|
||||
HAL_Delay(500);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user