信息安全系统设计基础实验五:简单嵌入式 WEB 服务器实验 (20125221,20135235,20135239)
北京电子科技学院(BESTI)
实 验 报 告
课程:信息安全系统设计 班级:1352
姓名:银雪纯 马悦 益西拉姆 学号:20125221 20135235 20135239
成绩: 指导教师:娄嘉鹏 实验日期:2015.12.8
实验密级: 预习程度: 实验时间:15:30—17:00
仪器组次: 必修/选修:必修 实验序号:05
实验名称: 简单嵌入式 WEB 服务器实验
实验目的与要求:(1)掌握在 ARM 开发板实现一个简单 WEB 服务器的过程。
(2)学习在 ARM 开发板上的 SOCKET 网络编程。
(3)学习 Linux 下的 signal()函数的使用。
实验仪器:
名称 |
型号 |
数量 |
嵌入式开发平台 |
UP-NETARM2410-CL |
1 |
PC机 |
|
1 |
实验内容:
学习使用 socket 进行通讯编程的过程,了解一个实际的网络通讯应用程序整体设计, 阅读 HTTP 协议的相关内容,学习几个重要的网络函数的使用方法。
读懂 HTTPD.C 源代码。在此基础上增加一些其他功能。在 PC 计算机上使用浏览器测试 嵌入式 WEB 服务器的功能。
实验步骤:
1、阅读理解源码
进入/home/bc/07_httpd 目录,
使用 vi 编辑器或其他编辑器阅读理解源代码
copy.c函数
#include <stdio.h>
static char copybuf[16384];
extern int TIMEOUT;
int copy(FILE *read_f, FILE *write_f)
{
int n;
int wrote;
alarm(TIMEOUT);
while (n = fread(copybuf,1,sizeof(copybuf),read_f)) {
alarm(TIMEOUT);
wrote = fwrite(copybuf,n,1,write_f);
alarm(TIMEOUT);
if (wrote < 1)
return -1;
}
alarm(0);
return 0;
}
alarm函数又被称为闹钟函数,alarm()用来设置信号AIGALRM经过seconds(参数)指定的秒数之后传送给目前的进程。需要注意的有两个地方:一个进程只能由一个闹钟时间,如果在调用alarm之前已经设置过闹钟时间,那么任何以前的闹钟都会被新闹钟取代;如果参数seconds设置为0,那么之前的闹钟会被取消。alarm只设定一个闹钟,时间到达并执行其注册函数之后,闹钟便失效。如果想循环设置闹钟,需在其注册函数中在调用alarm函数
httpd函数
主函数:
int main(int argc, char *argv[])
{
int fd, s;
int len;
volatile int true = 1;
struct sockaddr_in ec;
struct sockaddr_in server_sockaddr;
pthread_t th_key;
void * retval;
/*第一步,进行(中断)信号的处理*/
signal(SIGCHLD, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
signal(SIGALRM, sigalrm);
/*切换工作目录*/
chroot(HTTPD_DOCUMENT_ROOT);
printf("starting httpd...\n");
printf("press q to quit.\n");
// chdir("/");
/*第二步,输入命令并进行处理*/
if (argc > 1 && !strcmp(argv[1], "-i")) {
/* I'm running from inetd, handle the request on stdin */
fclose(stderr);
HandleConnect(0);
exit(0);
}
/*第三步,建立socket接口*/
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
perror("Unable to obtain network");
exit(1);
}
if((setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&true,
sizeof(true))) == -1) {
perror("setsockopt failed");
exit(1);
}
/*定义server_sockaddr结构体中的内容*/
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(SERVER_PORT);
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
/*第四步,对端口和地址进行绑定*/
if(bind(s, (struct sockaddr *)&server_sockaddr,
sizeof(server_sockaddr)) == -1) {
perror("Unable to bind socket");
exit(1);
}
/*第五步,监听端口*/
if(listen(s, 8*3) == -1) { /* Arbitrary, 8 files/page, 3 clients */
perror("Unable to listen");
exit(4);
}
/*第六步,多线程创建,等待连接*/
pthread_create(&th_key, NULL, key, 0);
/* Wait until producer and consumer finish. */
printf("wait for connection.\n");
while (1) {
len = sizeof(ec);
/*第七步,接收客户端连接请求*/
if((fd = accept(s, (void *)&ec, &len)) == -1) {
exit(5);
close(s);
}
HandleConnect(fd);
}
/*第八步,等待线程连接结束之后再结束main函数*/
pthread_join(th_key, &retval);
}
2、编译应用程序
先修改了Makefile:
然后运行make产生可执行文件httpd
3、下载调试
使用 NFS 服务方式将 HTTPD 下载到开发板上,并拷贝测试用的网页进行调试
在超级终端输入如下代码
4、本机测试
在台式机的浏览器中输入 http://192.168.0.121
(/192.168.0.121 为 UP-CUP S2410 实验板的 IP 地址)
实验总结:
这次实验还是使用124实验的实验环境,配置环境很顺利,开始进行make编译的时候出错,用实验4中的方法在/usr/src 下没有建立一个linux 连接,之后更改了一下Makefile的配置,就可以顺利编译了,之后超级终端的挂载都很顺利。
这次实验的体会是,不一定要全按指导书上的内容,比如Makefile的配置,挂载时的文件目录都要根据实际情况进行更改,才能实验成功。