STM32
直播中

tr12345

8年用户 928经验值
擅长:制造/封装
私信 关注
[问答]

stm32服务器是如何工作的

STM32服务器是如何工作的?

stm32服务器的通信过程是怎样的?

回帖(1)

陈臻江

2021-10-20 10:45:19
  最在做stm32 web服务器的东西,忙了一段时间终于弄完了,把这几天关于stm32服务器的工作记录一下。
  刚接到这个任务的时候,不知道怎么下手,网上资料似乎不是很多,于是在下载了一个官方demo测试了一下,看了一下代码,不是很懂,于是继续百度找资料,找到一个比较有用的网页,以下是链接: 最近在做stm32 web服务器的东西,忙了一段时间终于弄完了,把这几天关于stm32服务器的工作记录一下。刚接到这个任务的时候,不知道怎么下手,网上资料似乎不是很多,于是在下载了一个官方demo测试了一下,看了一下代码,不是很懂。
  其实,stm32 web服务器与pc网页的交互一般是以表单的方式,就两个接口,cgi和ssi。这两个东西我的理解是这样的,cgi 就是pc网页向stm32 web服务下发信息的接口,比如我们有这样的一个网页:
  《form method=‘get’ action=‘config.cgi’》
  《p》《label for=‘ip’》ip:《/label》《input type=‘text’ name=‘ip’ valu maxlengt /》《/p》
  《p》《label for=‘port’》port:《/label》《input type=‘text’ name=‘port’ valu maxlengt /》
  《/p》《p》《input type=‘submit’ value=‘保存’ /》《/p》
  《/form》
  如果看不懂这个网页的话,就百度一下吧,把上面东西复制到Macromedia Dreamweaver 8软件上就能看到是什么页面,上面在form就是表单,在《form》《/form》里面的内容就是表单的内容,里面有两个输入框,和一个保存按钮,当我们点出保存的时候就会在web服务器里触发,config.cgi的接口,关于web服务器的内容,后面再说,然后会把这个表单里的内容下发到服务器里,比如会把上面ip和port输入框中的数据发到web服务器里,web服务器就能获得想要的数据。接下来说一下ssi,我们可以拿个网络抓包软件观察一下,pc网页的web服务器的通信过程,其实也就是pc发送一个请求,然后web服务器返回一组数据,这组数据就是整个网页的内容。ssi的工作就是在这组返回的数据中嵌入一个要发送加pc端的数据在里面,比如刚才那个表单网页数据,我们要显示一些数据到ip输入框中,怎么办呢?在没有ssi接口的时候可以看到,
  《p》《labelfor=‘ip’》ip:《/label》《input type=‘text’ name=‘ip’ valu maxlengt /》《/p》 ,
  有ssi接口时候,我们就可以利用ssi接口改变返回的内容,比如:
  《p》《labelfor=‘ip’》ip:《/label》《input type=‘text’ name=‘ip’ valu maxlengt /》《/p》,
  可以看到 “《!--#ip--》192.168.1.1” 这个地方是不相同的,这时返回ip输入框是带着数据的,这个数据将显示在ip输入框内。
  接下来分析一下代码,首先看一下stm32官方http web 包里的文件
  fsdata.c,fsdata.h,是网页转换成的数组,
  fs.c, fs.h是操作fsdata.c里面数据的一些读写函数
  httpd.c, httpd.h函数是真正实现web服务器的文件
  httpd_cgi_ssi.c, httpd_cgi_ssi.h 就是刚才提到的cgi, ssi接口,
  一般我们只需要改动httpd_cgi_ssi.c, fsdata.c(这个文件是makefsfile.exe生成的),
  makefsfile里面又有一些什么文件呢
  fs文件夹是所有的网页,fsdata.c 是用makefsfile.exe转换得到的
  下面分析一下代码
  1. void httpd_init(void)
  {
  LWIP_DEBUGF(HTTPD_DEBUG, (“httpd_initn”));
  #if LWIP_HTTPD_SSI
  httpd_ssi_init(); //ssi接口初始化
  #endif
  #if LWIP_HTTPD_CGI
  httpd_cgi_init(); //cgi接口初始化
  #endif
  httpd_init_addr(IP_ADDR_ANY); //http web 相关初始化
  }
  2.ssi接口 要注意的一点就是 有ssi接口的网页要以 shtml为后缀
  char const* TAGS[]={ //这里定义了ssi标签,
  “ip”, //ip地址 对应网页里的《!--#ip--》
  “sp”, //服务器端口
  };
  u16_t DeviceSSI_Handler(int iIndex, char *pcInsert, int iInsertLen)
  {
  int len = 0;
  char buff[16];
  memset(buff,0,sizeof(buff));
  switch(iIndex)
  {
  case 0: //这个index是在数组中的位置
  sprintf(buff,“%s”,“192.168.1.1”);
  len = strlen(buff);
  memcpy(pcInsert,buff,len);// 这里是拷贝填充在ip标签里的内容
  break;
  case 1:
  。。。。。。
  break;
  }
  return len;
  }
  3.cgi接口
  //cgi接口定义
  tCGI CGI_TAB[]={
  {“/login.cgi”, LOGIN_CGI_Handler},
  {“/saveNet.cgi”, SAVE_NET_Handler} /*这里的cginame要和网页表单里的action相同《form method=‘get’ action=‘config.cgi’》*/
  };
  const char * SAVE_NET_Handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
  {
  uint32_t i=0;
  for (i=0; i《iNumParams/*参数数量*/; i++)
  {
  if(strcmp(pcParam/*参数名字,与网页里控件的name相同name=‘ip’*/,“ip”) == 0) //设备ip
  {
  printf(“ip is : %s rn”,pcValue/*控件的值*/);
  }
  else if(strcmp(pcParam,“port”) == 0)
  {
  。..
  }
  。..。..
  }
  cgi和ssi大概就这些内容要改的,
  4.打开网页里是哪一个为首页呢?在httpd.c里有一个数据
  //这里设置首页显示的html ,所以首页就是login
  const default_filename g_psDefaultFilenames[] = {
  {“/login.shtml”, true },
  {“/login.ssi”, true },
  {“/login.shtm”, true },
  {“/login.html”, false },
  {“/login.htm”, false }
  };
  5.我们发送ssi标签时会把标签一起发上去,这样在编辑控件里是会把标签一起显示的,比如valu,这不是我们想要的,怎么让它不发送标签呢,
  把httpd.c里的定义 #define LWIP_HTTPD_SSI_INCLUDE_TAG 1 //改为0就不发送标签
  6.还有一些比较常用的宏定义
  #define LWIP_HTTPD_MAX_CGI_PARAMETERS 16 //cgi数量定义
  #define LWIP_HTTPD_MAX_TAG_NAME_LEN 8 //定义tag标签长度定义
  #define LWIP_HTTPD_MAX_TAG_INSERT_LEN 192 //定义返回tag内容长度
举报

更多回帖

发帖
×
20
完善资料,
赚取积分