实验四-Web服务器2

技术实验四-Web服务器2 实验四-Web服务器2Web服务器
1.任务详情
基于华为鲲鹏云服务器CentOS中(或Ubuntu),使用Linux Socket实现:Web服务器的客户端服务器,提交程序

实验四-网络服务器2

Web服务器

1.任务详情

基于华为鲲鹏云服务器CentOS中(或Ubuntu),使用Linux操作系统套接字实现:

网服务器的客户端服务器,提交程序运行截图

实现得到即可,请求,响应要符合超文本传送协议协议规范

服务器部署到华为云服务器,浏览器用本机的

把服务器部署到试验箱。(加分项)

2.实验过程

代码部分直接使用了老师提供的代码,更改了部分地址位置与参数成功运行

copy.c

#包含stdio.h

静态char copy buf[16384];

外部int超时;

整数拷贝(FILE *read_f,FILE *write_f)

{

int n;

(同Internationalorganizations)国际组织写道;

警报(超时);

while (n=fread(copybuf,1,sizeof(copybuf),read _ f)){ 0

警报(超时);

write=fwrite(copy buf,n,1,write _ f);

警报(超时);

如果(写了1)

返回-1;

}

报警(0);

返回0;

}

httpd.c

#包含stdio.h

#包含stdlib.h

#包含fcntl.h

#包含字符串。h

#包含系统/类型。h

#包含系统/插座. h

#包含netinet/in.h

#包括errno.h

#包含系统/统计信息

#包括dirent.h

#包含信号。h

#包含unistd.h

#包括ctype.h

#包含" pthread.h "

#定义调试

int KEY _ QUIT=0;

(同Internationalorganizations)国际组织超时=30;

#ifndef O_BINARY

#定义O_BINARY 0

#endif

char referrer[128];

int内容_长度

#定义SERVER_PORT 80

int PrintHeader(FILE *f,int content_type)

{

警报(超时);

fprintf(f,' HTTP/1.0 200 OK \ n ');

开关(内容类型)

{

案例t':

fprintf(f,'内容类型:文本/纯文本\ n ');

打破;

案例g':

fprintf(f,'内容类型:图像/gif \ n ');

打破;

案例j':

fprintf(f,'内容类型:图像/JPEG \ n ');

打破;

案例h':

fprintf(f,' Content-type : text/html \ n ');

打破;

}

fprintf(f,' Server: UCLinux-httpd 0。2 .2 \ n ');

fprintf(f,' expires : 0 \ n ');

fprintf(f,' \ n ');

报警(0);

return(0);

}

int DoJpeg(FILE *f,char *name)

{

char * buf

文件*

(同Internationalorganizations)国际组织计数;

if(!(infile=fopen(name,' r ')(

警报(超时);

fprintf(stderr ,)无法打开联合图像专家组文件%s,%d\n ',名称,errno);

fflush(f);

报警(0);

返回-1;

}

PrintHeader(f,' j ');

副本(中缀,f);/*打印页面*/

警报(超时);

fclose(infile);

报警(0);

返回0;

}

int DoGif(FILE *f,char *name)

{

char * buf

文件*

(同Internationalorganizations)国际组织计数;

if(!(infile=fopen(name,' r ')(

警报(超时);

fprintf(stderr ,)无法打开GIF格式文件%s,

%d\n", name, errno);
fflush(f);
alarm(0);
return -1;
}

PrintHeader(f,'g');
copy(infile,f); /* prints the page */
alarm(TIMEOUT);
fclose(infile);
alarm(0);

return 0;
}
int DoDir(FILE *f, char *name)
{
char *buf;
DIR * dir;
struct dirent * dirent;
if ((dir = opendir(name))== 0) {
fprintf(stderr, "Unable to open directory %s, %d\n", name, errno);
fflush(f);
return -1;
}

PrintHeader(f,'h');

alarm(TIMEOUT);
fprintf(f, "H1Index of %s/H1\n\n",name);
alarm(0);
if (name[strlen(name)-1] != '/') {
strcat(name, "/");
}

while(dirent = readdir(dir)) {
alarm(TIMEOUT);

fprintf(f, "pa href=\"/%s%s\"%s/a/p\n", name, dirent-d_name, dirent-d_name);
alarm(0);
}

closedir(dir);
return 0;
}
int DoHTML(FILE *f, char *name)
{
char *buf;
FILE *infile;
int count;
char * dir = 0;
if (!(infile = fopen(name,"r"))) {
alarm(TIMEOUT);
fprintf(stderr, "Unable to open HTML file %s, %d\n", name, errno);
fflush(f);
alarm(0);
return -1;
}
PrintHeader(f,'h');
copy(infile,f); /* prints the page */
alarm(TIMEOUT);
fclose(infile);
alarm(0);
return 0;
}
int DoText(FILE *f, char *name)
{
char *buf;
FILE *infile;
int count;
if (!(infile = fopen(name,"r"))) {
alarm(TIMEOUT);
fprintf(stderr, "Unable to open text file %s, %d\n", name, errno);
fflush(f);
alarm(0);
return -1;
}
PrintHeader(f,'t');
copy(infile,f); /* prints the page */
alarm(TIMEOUT);
fclose(infile);
alarm(0);
return 0;
}
int ParseReq(FILE *f, char *r)
{
char *bp;
struct stat stbuf;
char * arg;
char * c;
int e;
int raw;
#ifdef DEBUG
printf("req is '%s'\n", r);
#endif

while(*(++r) != ' '); /*skip non-white space*/
while(isspace(*r))
r++;

while (*r == '/')
r++;
bp = r;

while(*r (*(r) != ' ') (*(r) != ''))
r++;

#ifdef DEBUG
printf("bp='%s' %x, r='%s' \n", bp, *bp,r);
#endif

if (*r == '')
{
char * e;
*r = 0;
arg = r+1;
if (e = strchr(arg,' '))
{
*e = '\0';
}
} else
{
arg = 0;
*r = 0;
}

c = bp;
/*zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz*/
if (c[0] == 0x20){
c[0]='.';
c[1]='\0';
}
/*zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz*/
if(c[0] == '\0') strcat(c,".");

if (c !stat(c, stbuf))
{
if (S_ISDIR(stbuf.st_mode))
{
char * end = c + strlen(c);
strcat(c, "/index.html");
if (!stat(c, stbuf))
{
DoHTML(f, c);
}
else
{
*end = '\0';
DoDir(f,c);
}
}
else if (!strcmp(r - 4, ".gif"))
DoGif(f,c);
else if (!strcmp(r - 4, ".jpg") || !strcmp(r - 5, ".jpeg"))
DoJpeg(f,c);
else if (!strcmp(r - 4, ".htm") || !strcmp(r - 5, ".html"))
DoHTML(f,c);
else
DoText(f,c);
}
else{
PrintHeader(f,'h');
alarm(TIMEOUT);
fprintf(f, "htmlheadtitle404 File Not Found/title/head\n");
fprintf(f, "bodyThe requested URL was not found on this server/body/html\n");
alarm(0);
}
return 0;
}
void sigalrm(int signo)
{
/* got an alarm, exit recycle */
exit(0);
}
int HandleConnect(int fd)
{
FILE *f;
char buf[160];
char buf1[160];
f = fdopen(fd,"a+");
if (!f) {
fprintf(stderr, "httpd: Unable to open httpd input fd, error %d\n", errno);
alarm(TIMEOUT);
close(fd);
alarm(0);
return 0;
}
setbuf(f, 0);
alarm(TIMEOUT);
if (!fgets(buf, 150, f)) {
fprintf(stderr, "httpd: Error reading connection, error %d\n", errno);
fclose(f);
alarm(0);
return 0;
}
#ifdef DEBUG
printf("buf = '%s'\n", buf);
#endif

alarm(0);
referrer[0] = '\0';
content_length = -1;

alarm(TIMEOUT);
//read other line to parse Rrferrer and content_length infomation
while (fgets(buf1, 150, f) (strlen(buf1) 2)) {
alarm(TIMEOUT);
#ifdef DEBUG
printf("Got buf1 '%s'\n", buf1);
#endif
if (!strncasecmp(buf1, "Referer:", 8)) {
char * c = buf1+8;
while (isspace(*c))
c++;
strcpy(referrer, c);
}
else if (!strncasecmp(buf1, "Referrer:", 9)) {
char * c = buf1+9;
while (isspace(*c))
c++;
strcpy(referrer, c);
}
else if (!strncasecmp(buf1, "Content-length:", 15)) {
content_length = atoi(buf1+15);
}
}
alarm(0);

if (ferror(f)) {
fprintf(stderr, "http: Error continuing reading connection, error %d\n", errno);
fclose(f);
return 0;
}

ParseReq(f, buf);
alarm(TIMEOUT);
fflush(f);
fclose(f);
alarm(0);
return 1;
}
void* key(void* data)
{
int c;
for(;;){
c=getchar();
if(c == 'q' || c == 'Q'){
KEY_QUIT=1;
exit(10);
break;
}
}

}
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(".");
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);
}
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.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);

}
pthread_join(th_key, retval);
}

Makefile

TOPDIR = /home/tzy/web/ws/07_httpd/
include $(TOPDIR)Rules.mak
EXTRA_LIBS += -lpthread
EXEC = $(INSTALL_DIR)  ./httpd
OBJS = httpd.o copy.o
HTTPD_DOCUMENT_ROOT = /home/tzy/web/ws/07_httpd/
CFLAGS += -DHTTPD_DOCUMENT_ROOT=\"$(HTTPD_DOCUMENT_ROOT)\"
all: $(EXEC)
$(EXEC): $(OBJS)
        $(CC) $(LDFLAGS) -o $@ $(OBJS) $(EXTRA_LIBS)
install:
        $(EXP_INSTALL) $(EXEC) $(INSTALL_DIR)
clean:
        -rm -f $(EXEC) *.elf *.gdb *.o

Rules.mak

TOPDIR= ..
CROSS = arm-linux-
CC= ${CROSS}gcc
#CC=gcc
#CFLAGS += -g
#LDFLAGS += -static  
EXTRA_LIBS +=
EXP_INSTALL = install -m 755
INSTALL_DIR = /home/tzy/web/ws/07_httpd/
  • 使用make命令导出可执行文件httpd,中间遇到的问题会在最后进行汇总

  • 但是发现软件无法执行,经查询发现是因为使用的是32bit的Ubuntu编译的

  • 重新调整,并更改了可执行文件名

  • 最后更新了tools工具,使用sudo dhclient进行联网,ipconfig查询地址发现地址为http://192.168.23.128/,实现结果如下

    代码链接:https://gitee.com/tang_zi_yue1927/code/tree/master/web/web/ws/07_httpd

  • 华为云欠费了,暂时无法实现


3.问题汇总

  • 首先执行发现无法识别Rules.mak中CROSS部分的armv4l-unknown-linux-,经上网查询下载了另一交叉编译器arm-linux-gcc
    • 使用sudo tar -xjvf /home/tzy/arm-linux-gcc-4.6.4-arm-x86_64.tar.bz2 -C /对在网上下载的压缩包进行解压
    • 解压完成后,再在(/usr/local)中创建一个新目录arm,即在Terminal中输入以下命令:sudo mkdir /usr/local/arm (因为已经实现故文件存在)
    • 创建arm目录成功后,还需要给它解放全部权限,即在Terminal中输入以下命令:sudo chmod 777 /usr/local/arm
    • 在解压出来的目录中找到并把整个gcc-4.6.4目录复制到刚刚建好的arm目录中,先cd切换到gcc-4.6.4所在目录(切换后先ls看一下有没有gcc-4.6.4目录):
      cd /opt/TuxamitoSoftToolchains/arm-arm1176jzfssf-linux-gnueabi/
    • 再执行 cp 复制命令,-r 表示整个目录以及里面的任何东西sudo cp -r gcc-4.6.4 /usr/local/arm
    • 打开(/etc/profile)配置环境变量和库变量,目的是以后可以在任何位置使用该交叉编译器,命令如下:sudo vim /etc/profile
    • 用vim打开后,在文件最后添加两行,并输入以下代码:第一行是添加执行程序的环境变量,第二行是库文件的路径:
1 export PATH=$PATH:/usr/local/arm/gcc-4.6.4/bin
2 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/gcc-4.6.4/lib

- 使用source命令重新加载生效该配置文件source /etc/profile
- 检验是否安装成功,在 Terminal 输入以下命令输出版本信息:arm-linux-gcc -v
结果如图所示:得到刚刚安装的4.6.4版

- 在 “/home/用户名” 目录下的 ".bashrc" 隐藏文件下加上和 “/etc/profile” 一样的两句

export PATH=$PATH:/usr/local/arm/gcc-4.6.4/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/gcc-4.6.4/lib

使用ls -a查看隐藏文件

参考网址:https://www.cnblogs.com/tansuoxinweilai/p/11602830.html

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/132062.html

(0)

相关推荐

  • 华氏度摄氏度对照表,1摄氏度等于多少华氏度

    技术华氏度摄氏度对照表,1摄氏度等于多少华氏度1摄氏度等于33.8华氏度。摄氏度的含义是指在1标准大气压下华氏度摄氏度对照表,纯净的冰水混合物的温度为0度,水的沸点为100度,其间平均分为100份,每一等份为1度,记作1

    生活 2021年10月22日
  • 生成JSON元数据对象的示例分析

    技术生成JSON元数据对象的示例分析生成JSON元数据对象的示例分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。数据验证是生成 JSON应用程序中最富

    攻略 2021年11月25日
  • Taro 3.4 beta 发布: 支持 Preact 为应用开辟更多体积空间

    技术Taro 3.4 beta 发布: 支持 Preact 为应用开辟更多体积空间 Taro 3.4 beta 发布: 支持 Preact 为应用开辟更多体积空间项目体积是困扰小程序开发者的一大问题,如

    礼包 2021年11月26日
  • mysql table_open_cache 到底有什么影响

    技术mysql table_open_cache 到底有什么影响mysql table_open_cache 到底有什么影响,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴

    攻略 2021年11月4日
  • 抖音刷播放,抖音刷多少播放可以上热门?

    技术抖音刷播放,抖音刷多少播放可以上热门?抖音的爆火引发了新的产业链的产生,点开百度输入关键词抖音上热门涨粉等等,就会出现很多的机构打着上热门,涨粉的这种幌子,制定出各种诱人的套餐,对抖音进行刷量,刷赞,换句话说只要你的

    测评 2021年11月11日
  • 零基础玩转SLS日志查询-SLS Query Builder发布

    技术零基础玩转SLS日志查询-SLS Query Builder发布 零基础玩转SLS日志查询-SLS Query Builder发布?简介:日志服务(Log Service,简称 SLS) 是阿里云提

    礼包 2021年11月25日