大部分的web server都是用JAVA、JS做的,查找了许多资料github上也只有寥寥数篇的几篇帖子,能用的真不多。后来经同事帮助在《嵌入式网络那些事STM32物联实战》这本书上找到了基于协议栈LWIP的web  server,建立服务器需要对HTTP协议、html网页有所了解,这样更利于设计代码完善功能(公司要求功能简单点灯、OTA升级、PWM波形输出、mesh网络配置)。

github示例:https://github.com/volkanunal/LwipFreertosWebServer

废话不多说直接上代码

一、tcp接口实现


#define HTTP_PORT 80
const unsigned char htmldata[] = "    \<html>   \<head><title> A LwIP WebServer !!</title></head> \<center><p>A WebServer Based on LwIP v1.4.1!</center>\</html>";static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{char *data = NULL;/* We perform here any necessary processing on the pbuf */if (p != NULL) {        /* We call this function to tell the LwIp that we have processed the data *//* This lets the stack advertise a larger window, so more data can be received*/tcp_recved(pcb, p->tot_len);data =  p->payload;if(p->len >=3 && (strncmp(data, "GET /", 5) == 0){tcp_write(pcb, htmldata, sizeof(htmldata), 1);}else{printf("Request error\n");}pbuf_free(p);tcp_close(pcb);     //断开连接,有可能导致打开不了网页} else if (err == ERR_OK) {/* When the pbuf is NULL and the err is ERR_OK, the remote end is closing the connection. *//* We free the allocated memory and we close the connection */return tcp_close(pcb);}return ERR_OK;
}/*** @brief  This function when the Telnet connection is established* @param  arg  user supplied argument * @param  pcb  the tcp_pcb which accepted the connection* @param  err     error value* @retval ERR_OK*/
static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{     tcp_recv(pcb, http_recv);return ERR_OK;
}/*** @brief  Initialize the http application  * @param  None * @retval None */
static void http_server_init(void)
{struct tcp_pcb *pcb = NULL;                       /* Create a new TCP control block  */pcb = tcp_new();                              /* Assign to the new pcb a local IP address and a port number *//* Using IP_ADDR_ANY allow the pcb to be used by any local interface */tcp_bind(pcb, IP_ADDR_ANY, HTTP_PORT);       /* Set the connection to the LISTEN state */pcb = tcp_listen(pcb);             /* Specify the function to be called when a connection is established */    tcp_accept(pcb, http_accept);   }

注意:1.一般会先发送消息报头head

例如:const static char http_html_hdr[] = "HTTP/1.1 200 OK\r\nContent-type:text/html\r\n\r\n";

但是现在直接发送网页实体也能正常显示网页,不同浏览器兼容性问题也会有影响

二、lwip的API接口实现网页控灯

const static char http_html_hdr[] = "HTTP/1.1 200 OK\r\nContent-type:text/html\r\n\r\n";const unsigned char LedOn_Data[] = "\<!DOCTYPE HTML>\<HTML>\<head>\<meta charset=\"UTF-8\">\<title>LED Monitor</title></head>\<body>\<center>\<p>\<center>LED 已打开!</center>\<form method=\"post\" action=\"off\" name=\"ledform\">\<font size=\"2\">改变LED状态:</font>  \<input type=\"submit\" value=\"关闭\">\</form>\</p>\</center>\</body>\</HTML>";   const unsigned char LedOff_Data[] = "\<!DOCTYPE HTML>\<HTML>\<head>\<meta charset=\"UTF-8\">\<title>LED Monitor</title></head>\<body>\<center>\<p>\<center>LED 已关闭!</center>\<form method=\"post\" action=\"on\" name=\"ledform\">\<font size=\"2\">改变LED状态:</font>  \<input type=\"submit\" value=\"打开\">\</form>\</p>\</center>\</body>\</HTML>";
const unsigned char testData[] = "\<HTML>1</HTML>";static bool led_on = FALSE;
void httpserver_send_html(struct netconn *conn, bool led_status)
{err_t err;//err = netconn_write(conn, http_html_hdr, sizeof(http_html_hdr)-1, NETCONN_NOCOPY); //不发送head的原因是发送了头,网页显示不了,空白,但可以和实体的数组合并一起发送,这样会更稳定printf("err = %d\n", err);if(led_status == TRUE) {netconn_write(conn, LedOn_Data, sizeof(LedOn_Data)-1, NETCONN_NOCOPY);} else {err = netconn_write(conn, LedOff_Data, sizeof(LedOff_Data)-1, NETCONN_NOCOPY);printf("err = %d\n", err);printf("%s,%d\n",__func__,__LINE__);}printf("%s,%d\n",__func__,__LINE__);
}void httpserver_serve(struct netconn *conn)
{struct netbuf *inbuf;err_t recv_err;char *buf;u16_t buflen;recv_err = netconn_recv(conn, &inbuf);printf("%s,%d\n",__func__,__LINE__);if(recv_err == ERR_OK) {if(netconn_err(conn) == ERR_OK) {netbuf_data(inbuf, (void**)&buf, &buflen);printf("%s,%d\n",__func__,__LINE__);if((buflen >= 5) && (strncmp(buf, "GET /", 5) == 0)) {httpserver_send_html(conn, led_on);printf("%s,%d\n",__func__,__LINE__);} else if((buflen >= 8) && (strncmp(buf, "POST", 4) == 0)) {printf("%s,%d\n",__func__,__LINE__);if(buf[6] == '0' && buf[7] == 'n') {led_on = TRUE;LED_ON();                //自己根据情况在这设置} else if(buf[6] == '0' && buf[7] == 'f' && buf[8] == 'f') {led_on = FALSE;LED_OFF();}httpserver_send_html(conn, led_on);}}netbuf_delete(inbuf);}netconn_close(conn);}static void
httpserver_thread(void *arg)
{struct netconn *conn, *newconn;err_t err;LWIP_UNUSED_ARG(arg);/* Create a new TCP connection handle */conn = netconn_new(NETCONN_TCP);LWIP_ERROR("http_server: invalid conn", (conn != NULL), return;);led_on = TRUE;LED_ON();  //根据实际情况编写函数/* Bind to port 80 (HTTP) with default IP address */netconn_bind(conn, NULL, 80);/* Put the connection into LISTEN state */netconn_listen(conn);do {err = netconn_accept(conn, &newconn);if (err == ERR_OK) {httpserver_serve(newconn);netconn_delete(newconn);}} while(err == ERR_OK);LWIP_DEBUGF(HTTPD_DEBUG,("http_server_netconn_thread: netconn_accept received error %d, shutting down",err));netconn_close(conn);netconn_delete(conn);
}/** Initialize the HTTP server (start its thread) */  //根据自身情况启用线程
void
httpserver_init()
{sys_thread_new("http_server_netconn", httpserver_thread, NULL, DEFAULT_THREAD_STACKSIZE, TCPIP_THREAD_PRIO + 1);
}

开启web server之前需要先保持开发板与服务器端处于同一网段,并能ping通,推荐使用google浏览器进行调试

在公司进行开发时还是要多进行debug和实验调试,祝大家早日完成任务

C语言编写web server相关推荐

  1. 利用go语言创建web server的两种方式

    相比于java/c#的mvc框架,go语言写web项目及其简单,创建一个web只需要简短的几行代码就可以实现功能: package mainimport "net/http"fun ...

  2. ABAP,Java, nodejs和go语言的web server编程

    ABAP and Java see my blog. nodejs 用nodejs现成的express module,几行代码就能写个server出来: var express = require(' ...

  3. node.js go java_ABAP,Java, nodejs和go语言的web server编程

    ABAP and Java see my blog). nodejs 用nodejs现成的express module,几行代码就能写个server出来: var express = require( ...

  4. ABAP,Java, nodejs和go语言的web server编程 1

    ABAP and Java see my blog). nodejs 用nodejs现成的express module,几行代码就能写个server出来: var express = require( ...

  5. 使用HTML语言编写HTML教程,HTML教程:HTML编写小经验

    在用HTML(HyperText Markup Language,超文本链接标示语言)语言编写Web页面时,由于所用的Web浏览器对HTML支持的程度不同,常常会在HTML语言的运用上产生一些疑问.在 ...

  6. java开发的图片管理系统,一个使用Java语言编写的Web本地照片管理系统

    jAlbum 这是一个使用Java语言编写的本地照片管理系统.使用BS架构.服务端采用Servlet提供RESTful风格接口和动态页面供浏览器直接访问,集成照片Exif信息处理.视频流信息处理和人像 ...

  7. 用C#和sql server语言编写的人事管理系统

    用C#和sql server语言编写的人事管理系统 博主作为一位新人刚自学完C#语言和SQL server也是第一次在CSDN这个程序猿的大家庭上发表博客,想通过这一篇博客与各位前辈进行学习交流,如写 ...

  8. 大型网站后台架构的Web Server与缓存

    1.1 Web server Web server 用来解析HTTP协议.当web服务器接收到一个HTTP请求时,会返回一个HTTP响应,例如送回一个HTML页面.为了处理一个请求,web服务器可以响 ...

  9. Web server调研分析

    简单可依赖的架构首先需要有一个简单可依赖的前端WebServer集群.本文通过深入调研当前主流的异步web服务器Lighttpd和Nginx,从业界使用情况.架构原理.扩展开发.功能对比.性能对比等多 ...

最新文章

  1. 软件架构设计之常用架构模式
  2. 研究发现,脸谱网和谷歌在流媒体上有广告跟踪器
  3. 【Linux部署】借助Docker部署Redis集群(Docker网卡创建+6个Redis集群搭建shell脚本)
  4. 20145209 实验三 《敏捷开发与XP实践》 实验报告
  5. 从流量控制算法谈网络优化-TCP核心原理理解
  6. matlab神经网络工具箱创建神经网络,matlab神经网络工具箱创建神经网络
  7. 揭秘!微软 Build 2020 开发者大会将启,邀您共赴线上新旅程
  8. [基础]PeopleSoft中的作业和调度作业集合定义
  9. python第2位的值_Python组通过匹配元组列表中的第二个元组值
  10. sscanf取固定长度的int_sscanf函数用法详解-阿里云开发者社区
  11. java 可选参数_超干货详解:kotlin(4) java转kotlin潜规则
  12. matlab 分数 函数,Matlab 中 residuez函数的使用
  13. CentOS6.0升级内核为6.2
  14. 4.3.2 信道编码 ——卷积码
  15. ET框架-02 ET框架-开发环境搭建
  16. [全国十大城市火车票售票点、订票电话(买票再也不用去火车站排队)] – [旅游] – [校内论坛]
  17. WPF 使用Image控件显示图片
  18. 搜狗浏览器屏蔽广告插件_搜狗浏览器屏蔽芒果TV视频广告:被判不正当竞争,赔了12万...
  19. 传统情感分类方法与深度学习的情感分类方法对比
  20. QPS达到30万的elasticsearch架设之道

热门文章

  1. CSDN优秀博客链接,博客之星链接。
  2. 企业数据备份方案-MxsDoc的自动备份的应用
  3. Word处理控件Aspose.Words功能演示:使用 Android 库将 Word 文档转换为 PDF
  4. 国内常用的Android镜像下载地址(附教育网主要镜像站)
  5. 如何使用WRLD构建交互式历史地图
  6. 在vue-cli中以烤串风格命名变量和属性
  7. 入选《PHP领域内容榜》第4名
  8. Bugku 猫片(安恒)(Stegsolve分析)
  9. 位图文件解析-位图(bmp)、图标(ico)与光标(cur)
  10. ProcessOn创建半圆