嵌入式环境下如何更新web server上html的一种参考方法

        前篇文章简单介绍了嵌入式Linux下boa web server的配置情况,将机器设备当作服务器,从而可以从PC上的浏览器上访问查看机器的一些运行状态信息,方便远程监视。

        由于数据的更新只存在于机器本地,本地进程如何与服务器进行数据传输是个问题,目前为止网上常见的方法主要是CGI和SET COOKIE.

CGI

        CGI,千禧年左右流行的一种方式,知网上搜索的论文也几乎是00年代左右的,虽然很古老,但是对于有限客户端的访问还是一种不错有用的方法(廉颇老矣,尚能饭!),其使用流程是,在客户端访问的html里添加表单动作(form action=“xxx.cgi”),指明当提交(submit)表单后调用执行xxx.cgi程序,该程序可用python、Perl、C/C++等语言完成,内容是通过getenv("QUERY_STRING")或读取标准输入来(前者GET方式后者POST方式)解析html传输的数据,然后在该CGI里通过printf方式逐行打印出一个要显示的页面内容作为输出,从而浏览器上显示的内容也随着更新。

        但若是一个页面有上千行,那么就不适用了。

SET COOKIE

流程大致类同于CGI,下面提供一个简单的代码例子。

index.html

<html>
 <head>
 <title>获取CGI数据</title>
 </head>
 <body>
  <form action="cgi-bin/getdata.cgi" method="get">
     <input type="submit" value="获取CGI中的数据 &rarr;">
  </form>
 </body>
</html>

getdata.c(交叉编译成后缀为cgi的文件)

#include <stdio.h>
#include "cgic.h"
#include <string.h>
#include <stdlib.h>
int cgiMain() 
{  

	printf("Set-Cookie: %s=%s;  path=/\r\n","Data","abcd");
	//设置一个名为Data数据为"abcd"的Cookie
	printf("Content-type:text/html;charset=utf-8\n\n");//cgiHeaderContentType("text/html");
	printf("<HTML><BODY>\n");
	printf("<HEAD>\n");
	printf("<meta http-equiv=\"Refresh\" content=\"0; URL=../showCookie.html\">\n");   
	//设置跳转到当前目录下的showCookie.html页面
	printf("<TITLE>Cookie</TITLE>\n");
	printf("</HEAD>\n");
	printf("</BODY>\n");
	printf("</HTML>\n");

	return 0;
}

showCookie.html

<html>
 <head>
<script type="text/javascript" >
function getCookie(c_name)
{
    if (document.cookie.length>0)
    {
         c_start=document.cookie.indexOf(c_name + "=")
         if (c_start!=-1)
         { 
            c_start=c_start + c_name.length+1 
            c_end=document.cookie.indexOf(";",c_start)
         if (c_end==-1) c_end=document.cookie.length
         return unescape(document.cookie.substring(c_start,c_end))
        } 
    }
return ""
}
</script>
 <title>显示Cookie数据</title>
 </head>
<body>
  <form >
    显示Cookie中的数据: Data=
    <input name="lignt_now" type="text" id="data_text"  />
  </form>
<script type="text/javascript" >
    bang_text= document.getElementById('data_text');            
    bang_text.value =getCookie('Data')
</script>
</body>
</html>

通过cgi文件中设置cookie,并安排关键词为‘Data’的值为“abcd”,在跳转到的showCookie.html中,通过getCookie('Data')获取得到“abcd”并将其显示到界面上,达到更新的目的。

        但如果浏览器禁用了cookie功能(比如不想让浏览器记录用户名密码等情况),该方法就失效了。

        上述两种方法都利用到了cgi及printf,优缺点均有,酌情使用。

        下面主要描述下第三种方法。

SED

        比较了解Linux的同学应该知道,sed其实是Linux下的一个命令,用来修改文本文件行内容的。没错,这种方法就是不使用以上的cgi和printf方法,而是简单粗暴的替换html某行内容来实现网页内容的更新,比如修改第23行内容,则只需执行sed -i '23c hello world' index.html即可。

        但也有缺点,比如浏览器必须禁用cookie这些功能,防止页面刷新不了,再比如需要手动刷新页面才能显示最新的页面内容。

        说个小插曲,当浏览器设置禁用cookie后,通过扫描二维码的方式登录CSDN,会发生二维码失效的事件(手机提示登录成功,浏览器页面显示二维码失效),取消禁用后再次扫描正常。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
问题一:套接字(Socket)是一种通信机制,用于在计算机网络中进行进程间通信或不同计算机之间的数据传输。它是一种抽象的概念,表示网络通信中的一个端点,包括IP地址和端口号。 问题二:以下是使用多线程实现嵌入系统的Web服务器的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <pthread.h> #define MAX_CLIENTS 10 #define BUFFER_SIZE 1024 void *handle_client(void *arg); int main(int argc, char *argv[]) { int server_socket, client_socket, addr_size; struct sockaddr_in server_addr, client_addr; pthread_t threads[MAX_CLIENTS]; // 创建服务器套接字 if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Error creating server socket"); exit(EXIT_FAILURE); } // 初始化服务器地址结构体 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(8080); // 绑定套接字到地址和端口 if (bind(server_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) { perror("Error binding server socket"); exit(EXIT_FAILURE); } // 开始监听客户端连接请求 if (listen(server_socket, MAX_CLIENTS) == -1) { perror("Error listening for client connections"); exit(EXIT_FAILURE); } printf("Server is running on port %d...\n", ntohs(server_addr.sin_port)); while (1) { addr_size = sizeof(client_addr); // 接受客户端连接请求 if ((client_socket = accept(server_socket, (struct sockaddr *) &client_addr, &addr_size)) == -1) { perror("Error accepting client connection"); continue; } printf("Client connected: %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); // 创建新线程处理客户端请求 pthread_create(&threads[MAX_CLIENTS], NULL, handle_client, (void *) &client_socket); } return 0; } void *handle_client(void *arg) { int client_socket = *(int *) arg; char buffer[BUFFER_SIZE]; ssize_t size; // 接收客户端请求 if ((size = recv(client_socket, buffer, BUFFER_SIZE, 0)) == -1) { perror("Error receiving client request"); close(client_socket); return NULL; } printf("Received client request: %s\n", buffer); // 响应客户端请求 char *response = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<html><head><title>Hello World</title></head><body><h1>Hello World!</h1></body></html>\r\n"; if (send(client_socket, response, strlen(response), 0) == -1) { perror("Error sending server response"); } close(client_socket); return NULL; } ``` 该示例代码使用多线程来处理每个客户端请求,每当有一个客户端连接时,就会创建一个新的线程来处理该客户端请求。该服务器可以同时处理多个客户端请求,但由于嵌入系统的性能限制,同时处理的客户端数量应该有限制。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值