简单Web服务器程序设计与实现

这篇具有很好参考价值的文章主要介绍了简单Web服务器程序设计与实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目描述:      

  1. 实现提供静态网页服务的web服务器

  2. 实现提供cgi动态网页服务的web服务器

  3. web服务器实现多进程服务

一、综合实践目的与要求

Linux程序设计综合实践是我们软件工程专业必须经历的过程,是理论与实践相结合的重要方式,使我们在实践中了解Linux操作系统、在实践中巩固知识。实习是个人综合能力的检验,除了有一定的课本知识外,还需有一定的实践动手能力,操作能力。实习是对我们软件工程专业知识的一种检验,它让我们学到了很多在课堂上根本就学不到的知识,技能开阔视野,又能增长见识,为我们走向工作打下坚实的基础,也是我们走向工作岗位的第一步。为了将所学的专业理论知识运用与实践,在实践中结合理论加深对其认识和总结。将专业与实际接轨,逐步认识,体会,从而更好地将所学的运用到工作中去。接触操作系统,认识linux,学会C语言,学会向老师提问,学会团结协作。通过深入编写程序,了解Linux和操作系统的现状,可加深理解并巩固所学专业知识,进一步提高认识问题、分析问题、解决问题的能力,使一个软件工程专业的学生应在linux综合实践与设计中用所学知识解决现实中的一些问题,对所学专业理论和实践知识进行巩固,同时提高自学、独立开发和协作能力,为走向工作岗位奠定良好的基础。

综合实践的要求是: 一、要求学生在实习过程中认真学习技术知识,积极与指导老师和同学配合;二、在前期,按时到勤,认真学习。积极做好实习日志,能够理解当天的内容。对技术的理论知识要及时实践;三、在后期,积极与同学沟通,认真完成项目要求的内容。在这个过程中要与老师同学多做沟通,通过探讨项目的`解决方案以及进展。

二、综合实践任务

       完成一个简单Web服务器程序设计与实现,要求学习网络套接字编程,HTTP协议、web服务器等知识;设计一个简单Web服务器,提供静态网页浏览服务功能;Web服务器可以配置的参数有主目录、首页问价名、HTTP端口号等项。

  1. 学习socket编程、http协议,实现提供静态网页的web服务器;
  2. 学习cgi知识,实现提供cgi动态网页服务的web服务器;
  3. Web服务器支持多进程服务。

三、总体设计

  1. 学习web服务器的基本原理。
  2. 学习socket网络编程。
  3. 学习http协议,实现提供静态网页的web服务器。
  4. 学习cgi知识,实现动态网页服务的web服务器。
  5. 运用多线程的知识,实现并发的web服务器。

四、详细设计说明

  • 了解web服务器的基本原理。Web服务器其实就是一类网络服务器,可以提供人们上网时向浏览器发出一些请求的一种程序。web服务器同时是一种比较被动的程序,只有你在上网的时候发出指令,这时服务器才会响应。

简单Web服务器程序设计与实现

 文章来源地址https://www.toymoban.com/news/detail-472431.html

  • 所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议栈进行交互的接口。

简单Web服务器程序设计与实现

 

  • 学习http协议实现,静态web服务器。超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出;而消息内容则具有一个类似MIME的格式。这个简单模型是早期Web成功的有功之臣,因为它使开发和部署非常地直截了当。

简单Web服务器程序设计与实现

 

  • 学习cgi的相关知识,实现提供动态网页的web服务器。

简单Web服务器程序设计与实现

 

程度实现:

hanshu.h

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>

#define SERVER_PORT 80
static int debug = 1;

int get_line(int sock, char* buf, int size);
void* do_http_request(void* client_sock);
void do_http_response(int client_sock, const char* path);
int  headers(int client_sock, FILE* resource);
void cat(int client_sock, FILE* resource);
void not_found(int client_sock);//404 
void unimplemented(int client_sock);//500
void bad_request(int client_sock); //400
void inner_error(int client_sock);

http.c

#include "hanshu.h"

void* do_http_request(void* pclient_sock) {
	int len = 0;
	char buf[256];
	char method[64];
	char url[256];
	char path[256];
	int client_sock = *(int*)pclient_sock;
	struct stat  st;

	//读取客户端发送的http请求
	len = get_line(client_sock, buf, sizeof(buf));

	if (len > 0) {
		int i = 0, j = 0;
		while (!isspace(buf[j]) && (i < sizeof(method) - 1)) {
			method[i] = buf[j];
			i++;
			j++;
		}

		method[i] = '\0';
		if (debug) printf("request method: %s\n", method);

		if (strncasecmp(method, "GET", i) == 0) { //处理get请求
			if (debug) printf("method = GET\n");

			//获取url
			while (isspace(buf[j++]));
			i = 0;
			while (!isspace(buf[j]) && (i < sizeof(url) - 1)) {
				url[i] = buf[j];
				i++;
				j++;
			}
			url[i] = '\0';
			if (debug) printf("url: %s\n", url);
			do {
				len = get_line(client_sock, buf, sizeof(buf));
				if (debug) printf("read: %s\n", buf);

			} while (len > 0);
			//处理url中的?
			{
				char* pos = strchr(url, '?');
				if (pos) {
					*pos = '\0';
					printf("real url: %s\n", url);
				}
			}
			sprintf(path, "./html_docs/%s", url); // html_doc 网页目录
			if (debug) printf("path: %s\n", path);

			//判断文件是否存在,如果不存在,就响应 404 NOT FOUND.
			if (stat(path, &st) == -1) {//文件不存在或是出错
				fprintf(stderr, "stat %s failed. reason: %s\n", path, strerror(errno));
				not_found(client_sock);
			}
			else {//文件存在

				if (S_ISDIR(st.st_mode)) {
					strcat(path, "/index.html");// 如果是ip地址,则添加主页路径
				}
				do_http_response(client_sock, path);
			}
		}
		else {//非get请求响应客户端 501 	Method Not Implemented
			fprintf(stderr, "warning! other request [%s]\n", method);
			do {
				len = get_line(client_sock, buf, sizeof(buf));
				if (debug) printf("read: %s\n", buf);

			} while (len > 0);

			unimplemented(client_sock);   //请求未实现

		}
	}
	else {//请求格式有问题,出错处理
		bad_request(client_sock);   //在响应时再实现
	}
	close(client_sock);
	if (pclient_sock) free(pclient_sock);//释放动态分配的内存
	return NULL;
}

void do_http_response(int client_sock, const char* path) {
	int ret = 0;
	FILE* resource = NULL;

	resource = fopen(path, "r");

	if (resource == NULL) {
		not_found(client_sock);
		return;
	}

	//1.发送http 头部
	ret = headers(client_sock, resource);

	//2.发送http body .
	if (!ret) {
		cat(client_sock, resource);
	}
	fclose(resource);
}

realization.c

#include "hanshu.h"

// 响应文件的头部
int  headers(int client_sock, FILE* resource) {
	struct stat st;
	int fileid = 0;
	char tmp[64];
	char buf[1024] = { 0 };
	strcpy(buf, "HTTP/1.0 200 OK\r\n");
	strcat(buf, "Server: Martin Server\r\n");
	strcat(buf, "Content-Type: text/html\r\n");
	strcat(buf, "Connection: Close\r\n");

	fileid = fileno(resource);

	if (fstat(fileid, &st) == -1) {
		inner_error(client_sock);
		return -1;
	}

	snprintf(tmp, 64, "Content-Length: %ld\r\n\r\n", st.st_size);
	strcat(buf, tmp);
	if (debug) fprintf(stdout, "header: %s\n", buf);
	if (send(client_sock, buf, strlen(buf), 0) < 0) {
		fprintf(stderr, "send failed. data: %s, reason: %s\n", buf, strerror(errno));
		return -1;
	}
	return 0;
}

// 读取内容,发送给客户端
void cat(int client_sock, FILE* resource) {
	char buf[1024];

	fgets(buf, sizeof(buf), resource);

	while (!feof(resource)) {
		int len = write(client_sock, buf, strlen(buf));

		if (len < 0) {//发送body 的过程中出现问题,怎么办?1.重试? 2.
			fprintf(stderr, "send body error. reason: %s\n", strerror(errno));
			break;
		}

		if (debug) fprintf(stdout, "%s", buf);
		fgets(buf, sizeof(buf), resource);

	}
}


//返回值: -1 表示读取出错, 等于0表示读到一个空行, 大于0 表示成功读取一行
int get_line(int sock, char* buf, int size) {
	int count = 0;
	char ch = '\0';
	int len = 0;

	while ((count < size - 1) && ch != '\n') {
		len = read(sock, &ch, 1);

		if (len == 1) {
			if (ch == '\r') {
				continue;
			}
			else if (ch == '\n') {
				break;
			}
			//处理一般的字符
			buf[count] = ch;
			count++;
		}
		else if (len == -1) {//读取出错
			perror("read failed");
			count = -1;
			break;
		}
		else {// read 返回0,客户端关闭sock 连接.
			fprintf(stderr, "client close.\n");
			count = -1;
			break;
		}
	}
	if (count >= 0) buf[count] = '\0';
	return count;
}


void not_found(int client_sock) {
	const char* reply = "HTTP/1.0 404 NOT FOUND\r\n\
Content-Type: text/html\r\n\
\r\n\
<HTML lang=\"zh-CN\">\r\n\
<meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\r\n\
<HEAD>\r\n\
<TITLE>NOT FOUND</TITLE>\r\n\
</HEAD>\r\n\
<BODY>\r\n\
	<P>文件不存在!\r\n\
    <P>The server could not fulfill your request because the resource specified is unavailable or nonexistent.\r\n\
</BODY>\r\n\
</HTML>";

	int len = write(client_sock, reply, strlen(reply));
	if (debug) fprintf(stdout, reply);

	if (len <= 0) {
		fprintf(stderr, "send reply failed. reason: %s\n", strerror(errno));
	}


}

void unimplemented(int client_sock) {
	const char* reply = "HTTP/1.0 501 Method Not Implemented\r\n\
Content-Type: text/html\r\n\
\r\n\
<HTML>\r\n\
<HEAD>\r\n\
<TITLE>Method Not Implemented</TITLE>\r\n\
</HEAD>\r\n\
<BODY>\r\n\
    <P>HTTP request method not supported.\r\n\
</BODY>\r\n\
</HTML>";

	int len = write(client_sock, reply, strlen(reply));
	if (debug) fprintf(stdout, reply);

	if (len <= 0) {
		fprintf(stderr, "send reply failed. reason: %s\n", strerror(errno));
	}
}

void bad_request(int client_sock) {
	const char* reply = "HTTP/1.0 400 BAD REQUEST\r\n\
Content-Type: text/html\r\n\
\r\n\
<HTML>\r\n\
<HEAD>\r\n\
<TITLE>BAD REQUEST</TITLE>\r\n\
</HEAD>\r\n\
<BODY>\r\n\
    <P>Your browser sent a bad request!\r\n\
</BODY>\r\n\
</HTML>";

	int len = write(client_sock, reply, strlen(reply));
	if (len <= 0) {
		fprintf(stderr, "send reply failed. reason: %s\n", strerror(errno));
	}
}


void inner_error(int client_sock) {
	const char* reply = "HTTP/1.0 500 Internal Sever Error\r\n\
Content-Type: text/html\r\n\
\r\n\
<HTML lang=\"zh-CN\">\r\n\
<meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\r\n\
<HEAD>\r\n\
<TITLE>Inner Error</TITLE>\r\n\
</HEAD>\r\n\
<BODY>\r\n\
    <P>服务器内部出错.\r\n\
</BODY>\r\n\
</HTML>";

	int len = write(client_sock, reply, strlen(reply));
	if (debug) fprintf(stdout, reply);

	if (len <= 0) {
		fprintf(stderr, "send reply failed. reason: %s\n", strerror(errno));
	}


}

Web_Server.c

#include "hanshu.h"

int main(void) {

	int sock;
	struct sockaddr_in server_addr;

	sock = socket(AF_INET, SOCK_STREAM, 0);
	bzero(&server_addr, sizeof(server_addr));

	server_addr.sin_family = AF_INET;//IPV4
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//监听本地所有IP地址
	server_addr.sin_port = htons(SERVER_PORT);//绑定端口号

	bind(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
	listen(sock, 128);
	printf("等待客户端的连接\n");

	int done = 1;
	while (done) {
		struct sockaddr_in client;
		int client_sock, len, i;
		char client_ip[64];
		char buf[256];
		pthread_t id;
		int* pclient_sock = NULL;

		socklen_t  client_addr_len;
		client_addr_len = sizeof(client);
		client_sock = accept(sock, (struct sockaddr*)&client, &client_addr_len);

		//打印客户端IP地址和端口号
		printf("client ip: %s\t port : %d\n",inet_ntop(AF_INET, &client.sin_addr.s_addr, client_ip, sizeof(client_ip)),ntohs(client.sin_port));

		//启动线程处理http请求
		pclient_sock = (int*)malloc(sizeof(int));
		*pclient_sock = client_sock;

		pthread_create(&id, NULL, do_http_request, (void*)pclient_sock);
	}
	close(sock);
	return 0;
}

结果演示

简单Web服务器程序设计与实现

简单Web服务器程序设计与实现 

 简单Web服务器程序设计与实现

 简单Web服务器程序设计与实现

 

到了这里,关于简单Web服务器程序设计与实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 课堂签到微信小程序的设计与实现 服务器Java+MySQL(附源码 调试 文档)

    摘要 本文介绍了一种《课堂签到微信小程序的设计与实现》。该系统分为三种用户角色,分别是管理员、教师和学生。管理员主要负责班级管理、学生管理、教师管理、课程管理、签到管理、请假管理和系统管理;教师用户主要进行注册登录、学生信息查看、课程信息查看、

    2024年02月05日
    浏览(46)
  • 基于微信小程序的网上购物平台小程序的设计与实现 服务器端口php+mysql(附源码 调试 文档)

    摘要 本文介绍了一种基于微信小程序的网上购物平台小程序,该系统主要分为两种用户角色,分别是管理员和用户。管理员主要负责分类管理、商品管理、订单管理、评价管理和系统管理等操作,而用户主要进行商品搜索、分类筛选、商品详细信息查看、在线下单、购物车管

    2024年02月05日
    浏览(58)
  • 基于SSM的服务器运维管理的论坛系统+98166(免费领源码+开发文档)可做计算机毕业设计JAVA、PHP、爬虫、APP、小程序、C#、C++、python、数据可视化、大数据、全套文案

    随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,服务器运维管理的论坛系统当然也不能排除在外。服务器运维管理的论坛系统是以实际运用为开发背景,运用软件工程原理和开发方法,采用 SSM技术构

    2024年01月16日
    浏览(57)
  • Web 服务器 -【Tomcat】的简单学习

    1.1 什么是Web服务器 Web服务器是一个应用程序( 软件 ),对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷。主要功能是\\\"提供网上信息浏览服务\\\"。 Web服务器是安装在服务器端的一款软件,将来我们把自己写的Web项目部署到Web Tomcat服务器软

    2024年02月13日
    浏览(43)
  • 配置web服务器+编写简单页面+分析交互过程

    目录 配置web服务器 IIS配置web服务器 C++搭建简单的web服务器 编写web页面 程序测试 IIS配置测试 C++程序测试 Wireshark捕获交互过程及分析 三次握手 请求报文 请求行 请求头 请求体 响应报文 响应行 响应头 响应体 四次挥手 实验中遇到的问题及分析 参考资料 使用Windows自带的II

    2024年02月08日
    浏览(48)
  • C语言-写一个简单的Web服务器(三)

    上次我们研究了如何将解析web前端的请求,本次内容里我们将服务器的内容响应到前端,让浏览器展示。 服务器将数据响应到前端有其必要的返回数据,其结构如下,中间rn为换行,这个在不同系统(window,linux)不同,暂时将其作为一种固定格式。 在这里插入代码片 “

    2024年03月16日
    浏览(45)
  • C语言-写一个简单的Web服务器(一)

    C语言可以干大事,我们基于C语言可以完成一个简易的Web服务器。当你能够自行完成web服务器,你会对C语言有更深入的理解。对于网络编程,字符串的使用,文件使用等等都会有很大的提高。 关于网络的TCP协议在这里不在多说,大家可以查阅些资料。 开发工具: CLion,编译

    2024年03月12日
    浏览(48)
  • 【Go Web 篇】从零开始:构建最简单的 Go 语言 Web 服务器

    随着互联网的迅速发展,Web 服务器成为了连接世界的关键组件之一。而在现代编程语言中,Go 语言因其卓越的性能和并发能力而备受青睐。本篇博客将带你从零开始,一步步构建最简单的 Go 语言 Web 服务器,让你对 Go 语言的 Web 开发能力有一个初步的了解。 在选择一门语言

    2024年02月11日
    浏览(54)
  • Web端服务器推送技术原理分析及dwr框架简单的使用(1)

    随着 Ajax技术的兴起,让广大开发人员又一次看到了使用浏览器来替代桌面应用的机会,并且这次机会非常大。Ajax将整个页面的刷新变成页面局部的刷新,并且数据的传送是以异步方式进行,这使得网络延迟带来的视觉差异将会消失。 但是,在浏览器中的 Ajax应用中存在一

    2024年04月25日
    浏览(35)
  • WebServer项目(四)->(基于Proactor的c++)Web服务器简介及简单实现

    Web Server(网页服务器)是一种软件程序,用于接收和处理来自客户端浏览器的HTTP请求,并向客户端浏览器提供HTML文档、图像、CSS和JavaScript等Web资源。 Web Server通常运行在服务器操作系统上,监听指定的端口,等待客户端浏览器发起HTTP请求。当收到HTTP请求后,Web Server会根据

    2024年02月12日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包