前言
本实验是实现一个简易的webserver,我们一直在访问网站,甚至还做过Web课程设计,部署过Tomcat等等,所以说这次实验能更深入的了解其原理
白嫖容易,创作不易,本文原创,转载请注明!!!
源码和可运行程序:
链接:https://pan.baidu.com/s/1A9KctmpP2JJgyW2wLrehIg
提取码:Lin2
计算机网络课程设计:
计算机网络课程设计之网络聊天程序的设计与实现
计算机网络课程设计之Tracert与Ping程序设计与实现
计算机网络课程设计之基于 IP 多播的网络会议程序
计算机网络课程设计之网络嗅探器的设计与实现
计算机网络课程设计之电子邮件客户端程序设计与实现
计算机网络课程设计之TELNET 终端设计与实现
计算机网络课程设计之网络代理服务器的设计与实现
计算机网络课程设计之简单 Web Server 程序的设计与实现
Qt入门系列:
Qt学习之C++基础
Qt学习之Qt安装
Qt学习之Qt基础入门(上)
Qt学习之Qt基础入门(中)
Qt学习之Qt基础入门(下)
创作不易,整个课程设计程序3000多行代码,所有实验都写在了一个程序中,时间有限,能力不足,转载望注明!!!
本文链接
个人博客:https://ronglin.fun/archives/278
PDF链接:见博客网站
CSDN: https://blog.csdn.net/RongLin02/article/details/122510631
实验题目
简单 Web Server 程序的设计与实现
实验目的
Web 服务是 Internet 最方便与受用户欢迎的服务类型,它的影响力也远远超出了专业技术范畴,已广泛应用于电子商务、远程教育、远程医疗与信息服务等领域,并且有继续扩大的趋势。目前很多的 Internet 应用都是基于 Web 技术的,因此掌握 Web 环境的软件编程技术对软件人员是至关重要的。编写简单的 Web Server 有助于读者了解 Web Server 的工作流程,掌握超文本传送协议( HTTP)基本原理,掌握 Windows 环境中用 socket 实现 C/S 结构程序的编程方法。附录 5 介绍了一个简单 Web Server 的程序设计过程。
总体设计
(含背景知识或基本原理与算法、或模块介绍、设计步骤等)
本次实验设计基于TCP连接,然后用HTTP协议,主要是对于HTTP头的解析然后返回对应的文件
先看Get请求的头文件
GET / HTTP/1.1
Host: 192.168.43.246:8088
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
有这么多的数据内容,关键的是第一行,表示的是Get
然后访问路径是/
协议是HTTP/1.1
之后就是一些基本的信息,例如Host访问地址,Connection是否保持连接等等
然后再来看一个Web Server的回应
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 122
<html>
...
</html>
首先是对请求的回应,200 ok,表示成功找到路径下的文件,然后第二行是一个RFC格式的时间戳,然后还有一些基本信息,最后就是返回的HTML的文件了。
详细设计
(含主要的数据结构、程序流程图、关键代码等)
原理已经明白,下面就是设计
首先要写一个构造头的函数
QString MyServer::getHeaderString(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: %1
QString header = "";
if(state == true)
{
header = header + "HTTP/1.1 200 OK" + "\r\n";
header = header + "Date: ";
header = header + QDateTime::currentDateTime().toString("ddd, d MMM yyyy hh:mm:ss") + " GMT\r\n";
header = header + "Content-Type: text/html;charset=ISO-8859-1" + "\r\n";
header = header + "Content-Length: %1" + "\r\n";
}
else if(state == false)
{
header = header + "HTTP/1.1 404 Not Found" + "\r\n";
header = header + "Date: ";
header = header + QDateTime::currentDateTime().toString(Qt::RFC2822Date) + " GMT\r\n";
header = header + "Content-Type: text/html;charset=ISO-8859-1" + "\r\n";
header = header + "Content-Length: 0" + "\r\n";
}
return header;
}
提供了2种返回值,一个是找到了,另一个是没找到。然后按照头格式构造
然后就是解析请求报文,分析请求路径
QString path = data.split(" ").at(1);
int result = -1;
if(path == "/") //访问根路径
{
QFile file(QDir::currentPath()+"/" +fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
emit this->sendError(QDir::currentPath()+"/" + fileName +" 打开失败");
result = socket->write(getHeaderString(false).toUtf8());
return;
}
QTextStream in(&file);
QString fileData = in.readAll();
result = socket->write((getHeaderString(true).arg(fileData.size()) + fileData +QString("\r\n")).toUtf8());
this->sendData("Server Response:\r\n"+ getHeaderString(true).arg(fileData.size()) + fileData +"\r\n");
// this->sendData("Server Response:\r\n"+ getHeaderString(true) + fileData);
}
上如,用' '
分割,然后找到第二个参数,如果是/
的话就是根路径,然后返回服务器设定的根路径文件
最后通过TCP,将头和文件数据都返回给客户端
实验结果与分析
启动服务器,它会输出一个网站,然后用浏览器打开这个网站,
请求成功
然后在软件界面显示调试信息
实验完成,但是只有一个问题就是浏览器一直在请求转圈,时间有限,没找到问题所在
小结与心得体会
Web Server太常用了,越是习以为常的东西,越不会注意到它的原理,这次通过自己设计,了解了 HTTP是如何用TCP实现的,获益匪浅
=w=