计算机网络课程设计-简单 Web Server 程序的设计与实现

目录

 

前言

1 实验题目

2 实验目的

3 实验内容

3.1 步骤

3.2 关键代码

3.2.1 利用Stringsplit函数将浏览器发送的请求头信息进行解析

3.2.2 利用getRfcTime函数将本地时间转换为浏览器需要的RFC时间格式

3.2.3 利用getHeader函数根据Stringsplit函数解析得到的请求信息生成成功响应头或失败响应头

3.2.4 利用getContent函数根据Stringsplit函数解析得到的请求路径生成相应的响应数据

4 实验结果与分析

5 代码


前言

        本实验为计算机网络课程设计内容,基本上所有代码都是根据指导书给的附录写出来的。有些实验需要实现图形界面,但是出于期末考试压力,我所有实验均是在控制台输入输出的,没有花额外时间去学习qt了,有精力的同学可以自学一下qt实现简单的图形界面。同时,该博客内容为部分报告内容,仅为大家提供参考,请勿直接抄袭。另外,本次实验所用平台是dev c++5.11

1 实验题目

        实验九 简单 Web Server 程序的设计与实现

2 实验目的

        Web 服务是 Internet 最方便与受用户欢迎的服务类型,它的影响力也远远超出了专业技术范畴,已广泛应用于电子商务、远程教育、远程医疗与信息服务等领域,并且有继续扩大的趋势。目前很多的 Internet 应用都是基于 Web 技术的,因此掌握 Web 环境的软件编程技术对软件人员是至关重要的。
        编写简单的 Web Server 有助于读者了解 Web Server 的工作流程,掌握超文本传送协议( HTTP)基本原理,掌握 Windows 环境中用 socket 实现 C/S 结构程序的编程方法。

3 实验内容

3.1 步骤

        (1)创建套接字并进行初始化。

        (2)绑定套接字到本地端口,用于监听来自客户端的连接。

        (3)循环接受客户端连接,接收并解析HTTP请求。

        (4)根据请求生成HTTP响应,发送给客户端。

3.2 关键代码

3.2.1 利用Stringsplit函数将浏览器发送的请求头信息进行解析

void Stringsplit(string str, const char split,vector& res) {
	/*
	GET / HTTP/1.1
	Host: 192.168.142.119:8000
	Connection: keep-alive
	Cache-Control: max-age=0
	Upgrade-Insecure-Requests: 1
	*/
	istringstream iss(str);	// 输入流
	string token;			// 接收缓冲区
	getline(iss, token,'\n');
	cout<<"token:"<

3.2.2 利用getRfcTime函数将本地时间转换为浏览器需要的RFC时间格式

char * getRfcTime() {
	time_t timep;
	struct tm *p;
	static char timeBuf[30];
	time(&timep); //获取从1970至今过了多少秒,存入time_t类型的timep
	p = localtime(&timep);//用localtime将秒数转化为struct tm结构体
	sprintf(timeBuf,"%s, %d %s %d %02d:%02d:%02d GMT\r\n",
	        wday[p->tm_wday],p->tm_mday,month[p->tm_mon],1900 + p->tm_year,p->tm_hour, p->tm_min, p->tm_sec);
	return timeBuf;
}

3.2.3 利用getHeader函数根据Stringsplit函数解析得到的请求信息生成成功响应头或失败响应头

string getHeader(bool state) {
	/*
	HTTP/1.1 200 OK
	Date: Sat, 31 Dec 2005 23:59:59 GMT
	Content-Type: text/html;charset=ISO-8859-1
	Content-Length:
	*/
	string header = "";
	if(state) {
		header = header + "HTTP/1.1 200 OK" + "\r\n";
		header = header + "Date: ";
		//Sat, 31 Dec 2005 23:59:59 GMT
		char *timeP = getRfcTime();
		char timeBuf[30] = "\0";
		strcpy(timeBuf,timeP);
		header = header +  + timeBuf;
		header = header + "Content-Type: text/html;charset=UTF-8" + "\r\n";
		header = header + "Content-Length: ";
	} else if(state == false) {
		header = header + "HTTP/1.1 404 Not Found" + "\r\n";
		header = header + "Date: ";
		char *timeP = getRfcTime();
		char timeBuf[30] = "\0";
		strcpy(timeBuf,timeP);
		header = header +  + timeBuf;
		header = header + "Content-Type: text/html;charset=UTF-8" + "\r\n";
		header = header + "Content-Length: ";
	}
	return header;
}

3.2.4 利用getContent函数根据Stringsplit函数解析得到的请求路径生成相应的响应数据

string getContent(vector res) {
	string content="";
	string header= "";
	int sendCode;
	if(res[1]=="/") {
		res[1]="index.html";
	} else {
		res[1]=res[1].substr(1,res[1].size());
	}
	ifstream infile;
	infile.open(res[1], ios::in);
	if (!infile.is_open()) {
		cout << "获取文件"<

4 实验结果与分析

(1)启动MyWebServer监听客户端请求。

计算机网络课程设计-简单 Web Server 程序的设计与实现_第1张图片

图1.1 启动MyWebServer

(2)实验项目的同级和二级目录下的文件信息。

计算机网络课程设计-简单 Web Server 程序的设计与实现_第2张图片

图1.2 项目的同级目录下的文件

计算机网络课程设计-简单 Web Server 程序的设计与实现_第3张图片

图1.3 项目的二级目录下的文件

(3)打开浏览器,在请求路径栏只输入ip地址和端口号响应index.htm

计算机网络课程设计-简单 Web Server 程序的设计与实现_第4张图片

图1.4 只输入ip地址和端口号

(4)请求其他的正确文件会响应相应的信息,例如请求hardwork.html、shiyan9.html、data.txt文件和/test/end.html文件。

计算机网络课程设计-简单 Web Server 程序的设计与实现_第5张图片

图1.5 请求hardwork.html

计算机网络课程设计-简单 Web Server 程序的设计与实现_第6张图片

图1.6 请求shiyan9.html文件中的信息

计算机网络课程设计-简单 Web Server 程序的设计与实现_第7张图片

图1.7 请求data.txt文件

计算机网络课程设计-简单 Web Server 程序的设计与实现_第8张图片

图1.8 请求/test/end.html文件

(5)请求不存在的目录文件显示404错误信息。

计算机网络课程设计-简单 Web Server 程序的设计与实现_第9张图片

图1.9 404错误信息

5 代码

//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include 
#include 

#include 
#pragma comment(lib,"ws2_32")

//#pragma comment ( lib  , "Protocol.lib" )

using namespace std;
typedef long long LL;
const int maxn = 10010;

const char *wday[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
const char *month[]   =  {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};

string html =
    "\n\
	\n\
		index.html\n\
	\n\
	\n\
		

This is index.html

\n\

你好

\n\ \n\ "; void Stringsplit(string str, const char split,vector& res) { /* GET / HTTP/1.1 Host: 192.168.142.119:8000 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 */ istringstream iss(str); // 输入流 string token; // 接收缓冲区 getline(iss, token,'\n'); cout<<"token:"<tm_wday],p->tm_mday,month[p->tm_mon],1900 + p->tm_year,p->tm_hour, p->tm_min, p->tm_sec); return timeBuf; } string getHeader(bool state) { /* HTTP/1.1 200 OK Date: Sat, 31 Dec 2005 23:59:59 GMT Content-Type: text/html;charset=ISO-8859-1 Content-Length: */ string header = ""; if(state) { header = header + "HTTP/1.1 200 OK" + "\r\n"; header = header + "Date: "; //Sat, 31 Dec 2005 23:59:59 GMT char *timeP = getRfcTime(); char timeBuf[30] = "\0"; strcpy(timeBuf,timeP); header = header + + timeBuf; header = header + "Content-Type: text/html;charset=UTF-8" + "\r\n"; header = header + "Content-Length: "; } else if(state == false) { header = header + "HTTP/1.1 404 Not Found" + "\r\n"; header = header + "Date: "; char *timeP = getRfcTime(); char timeBuf[30] = "\0"; strcpy(timeBuf,timeP); header = header + + timeBuf; header = header + "Content-Type: text/html;charset=UTF-8" + "\r\n"; header = header + "Content-Length: "; } return header; } string getContent(vector res) { string content=""; string header= ""; int sendCode; if(res[1]=="/") { res[1]="index.html"; } else { res[1]=res[1].substr(1,res[1].size()); } ifstream infile; infile.open(res[1], ios::in); if (!infile.is_open()) { cout << "获取文件"<h_addr_list[0][0]&0x00ff),(p->h_addr_list[0][1]&0x00ff), (p->h_addr_list[0][2]&0x00ff),(p->h_addr_list[0][3]&0x00ff),htons(addrSrv.sin_port)); cout<<"-------------------------------------------\n"; SOCKADDR_IN addrClient; int len=sizeof(SOCKADDR); int sendCode,recvCode; char recvBuf[2048]; char sendBuf[2048]; vector v; SOCKET tempSockConn; string sendStr=""; while(1) { cout<<"等待客户端连接\n"; SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); cout<<"\nsockConn:"<

你可能感兴趣的:(计算机网络,计算机网络)