配置web服务器+编写简单页面+分析交互过程

这篇具有很好参考价值的文章主要介绍了配置web服务器+编写简单页面+分析交互过程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

配置web服务器

IIS配置web服务器

C++搭建简单的web服务器

编写web页面

程序测试

IIS配置测试

C++程序测试

Wireshark捕获交互过程及分析

三次握手

请求报文

请求行

请求头

请求体

响应报文

响应行

响应头

响应体

四次挥手

实验中遇到的问题及分析

参考资料


配置web服务器

IIS配置web服务器

使用Windows自带的IIS配置web服务器,具体配置情况如下:

web配置界面,服务器,前端,交互

网站名称可以自己取,物理路径是我们编写的html文件所在的地方。

web配置界面,服务器,前端,交互

IP地址我设置成了本地,端口默认为80,也可以自由更改,注意不要和其他被使用的端口重复了!

web配置界面,服务器,前端,交互

我没有修改默认文档,因此我的html文件必须被命名为index.html,大家也可以自行修改。

C++搭建简单的web服务器

在C++实现流式socket聊天程序的基础上,我们也可以采用流式socket的方式搭建一个简单的web服务器。主要的流程大体相同,但是发送和接收消息的部分改为接收客户端访问页面的请求头,并发送响应报文

由于本实验的重点并非编程,我编写的程序中没有对客户的请求头进行分析,从而作出相应的处理,只是简单地接收请求头,并发送响应报文,响应体为我编写的html文件。

C++程序的主要代码如下(其他部分代码与实验1大体相同):

// 接收客户端的连接请求
while (true) {
    sockaddr_in addrClient;
    int len = sizeof(sockaddr_in);
    // 接收客户端的连接请求并创建新的套接字
    SOCKET sockConn = accept(sockServer, (SOCKADDR*)&addrClient, &len);
    if (sockConn != INVALID_SOCKET) {
        cout << "[ACCEPT CONNECTION REQUEST!]" << endl;
        cout << "---------------------------------------------------" << endl;
        char recvBuf[2652];
        memset(recvBuf, 0, sizeof(recvBuf));
        // 获取客户端的请求头
        int recvLen = recv(sockConn, recvBuf, 2652, 0);
        if (recvLen == -1) {
            cout << "Request error!" << endl;
            break;
        }
        else {
            cout << sizeof(recvBuf) << " bits received." << endl;
            cout << recvBuf << endl;
            cout << "---------------------------------------------------" << endl;

            // 响应报文
            char response[2652];
            memset(response, 0, sizeof(response));
            // 计算时间
            char tmp[32] = { NULL };
            time_t t = time(0);
            strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&t));
            string str = "HTTP/1.1 200 OK\r\n""Date: ";
            str.append(tmp);
            str.append(" GMT\r\n");
            // 响应头,随便写了一点,并不完整,详细的分析看下文介绍
            str.append("Server: Roslin's web server(Windows)\r\n"
                       "Content-length: 1583\r\n"
                       "Content-Type: text/html; charset=UTF-8\r\n"
                       "Keep-Alive: timeout=10, max=100\r\n"
                       "Connection: Keep-Alive\r\n\r\n");
            // Conten-length一定要和消息体(html文件)的长度一致!!!否则无法正确显示
            // 打开html文件,参数r表示仅供读取
            FILE* file = fopen("WebPage.txt", "r");
            if (file == NULL) {
                cout << "Can not open the file!" << endl;
                return 0;
            }
            char html[1024] = "";
            do {
                memset(html, 0, sizeof(html));
                fgets(html, 1024, file);
                str.append(html);
            } while (!feof(file));

            // 发送响应报文,发送的消息长度必须和实际的一致,太长了会读入乱码!!!
            strcpy_s(response, str.c_str());
            send(sockConn, response, str.length(), 0);
            cout << str.length() << " bits response sent." << endl;
            cout << str << endl;
            cout << "---------------------------------------------------" << endl;
        }
    }
    // 关闭监听套接字
    closesocket(sockConn);
}

虽然我的响应头发送的连接方式是Keep-Alive,但是大家可以看到我发送完响应报文之后就关闭监听了套接字,相当于关闭了TCP连接,这是因为之后我们需要捕获TCP四次挥手的过程(其实是因为我一开始没想清楚)

编写web页面

我编写了一个简单的html文件,用来显示我的个人主页。主要内容有姓名、学号、专业、学院、学校、个人logo(一只可爱的小考拉)。还加入了网易云音乐的外链接和背景图片,使界面更具有观赏性。具体的代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Roslin's Home Page</title>
    <style>
		body 
		{
			background-image: url(https://img.zmtc.com/2019/0815/20190815113422287.jpg);
			background-size: cover;
		}
	</style>
    <style>
    div.transbox
            {
              width: 1050px;
              height: 420px;
              margin: 90px 90px;
              background-color: #ffffff;
              border: 1px solid #FFFFFF;
              opacity:0.8;
            }
    </style>
    <style>
		h1 {text-align: center;}
		h2.ex1 {margin-left:5cm;}
		h3.ex1 {margin-left:5cm;}
		p{text-align: right;}
		p.ex1{margin-right: 2cm;}
	</style>
    <style>
   	img.ex1{margin-left:5cm;border-radius:100%;overflow:hidden;position: absolute;top: 50;left: 150;}
	</style>
</head>
<body>
	<div class="background">
		<div class="transbox">
            <h1>个人简介</h1>
            <h2 class="ex1">Roslin</h2>
            <h3 class="ex1">学号:xxx</h3>
            <h3 class="ex1">专业:xxx</h3>
            <h3 class="ex1">学院:xxx</h3>
            <h3 class="ex1">学校:xxx</h3>
            <p class="ex1">xxxxx</p>
            <img src="https://tupian.qqw21.com/article/UploadPic/2015-5/201552323315986462.jpg" height="150px" width="150px" class="ex1" title="logo"/>
		</div>
    </div>
    <iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=298 height=52 src="http://music.163.com/outchain/player?type=2&id=456370728&auto=1&height=32"></iframe>
</body>
</html>

注意:

  • 插入的图片如果是本地的,必须放在html文件的根目录之下,否则要放完整的地址。但是插入本地图片用C++编程的方式无法正确显示,用IIS配置的方式可以。
  • 用电脑浏览器打开网易云音乐,选择想要的歌曲/歌单,点击生成外链接,复制html代码即可。但是有些歌曲因版权问题无法生成外链接! 

特别声明:本人没学过html,因此界面非常简单。

程序测试

IIS配置测试

直接打开127.0.0.1(80端口为默认的,不用加),即可看到我编写的web页面,测试成功。

web配置界面,服务器,前端,交互

C++程序测试

运行WebServer.cpp,打开浏览器,输入localhost:81(程序中指定的本地ip及端口号),可以看到我编写的web页面,测试成功。

懒得放图...

Wireshark捕获交互过程及分析

使用Wireshark捕获交互过程,可以看到TCP握手、浏览器的GET请求、我编写的响应报文和TCP挥手。

web配置界面,服务器,前端,交互

三次握手

  1. 第一次握手:客户端发送序列号Seq=0的SYN报文到服务器,表示请求建立连接。
  2. 第二次握手:服务器收到客户端的SYN报文,发送序列号Seq=0、确认号Ack=1的SYN, ACK报文到客户端,表示同意建立连接。
  3. 第三次握手:客户端收到服务器的SYN, ACK报文,发送序列号Seq=1、确认号Ack=1的ACK报文到服务器,表示确认建立连接。

请求报文

GET / HTTP/1.1
Host: localhost:81
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="106", "Microsoft Edge";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.47
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6

请求行

  • 请求方法:GET, POST, HEAD, PUT, DELETE。
  • 请求url:在本实验中,由于是同一台主机,于是省略了。
  • http版本:在本实验中是HTTP/1.1。

请求头

  • Host:主机。
  • Connection:连接方式,keep-alive说明服务器在发送响应报文后不关闭TCP连接。
  • Cache-Control:缓存控制,max-age表示客户端希望接收资源的存在时间的最大值,在本实验中,意思是客户端希望接收一个新的资源。
  • sec-ch-ua:浏览器的版本。
  • sec-ch-ua-mobile:浏览器是否在移动设备上打开。
  • sec-ch-ua-platform:浏览器所在的操作系统。
  • Upgrade-Insecure-Requests:请求服务端支持以下升级机制。
  • User-Agent:客户端请求的相关信息,实验如浏览器、操作系统等。
  • Accept:客户端希望接收的响应体的数据类型。
  • Sec-Fetch-Site:表示一个请求发起者的来源与目标资源来源之间的关系。
    • cross-site:跨域请求;
    • same-origin:发起和目标站点源完全一致;
    • same-site:实验如一级请求二级域名;
    • none:如果用户直接触发页面导航,实验如在浏览器地址栏中输入地址,点击书签跳转等。
  • Sec-Fetch-Mode:请求的模式。
    • cors:跨域请求;
    • no-cors:限制请求,只能使用请求方法(get/post/put)和请求头(accept/accept-language/content-language/content-type);
    • same-origin:如果使用此模式向另外一个源发送请求,显而易见,结果会是一个错误。
    • navigate:表示这是一个浏览器的页面切换请求,仅在浏览器切换页面时创建,该请求应该返回html;
    • websocket:建立websocket连接。
  • Sec-Fetch-User:表示导航请求激发的原因。
    • true(?1):导航请求由用户激活触发(鼠标点击/键盘);
    • false(?0):导航请求由用户激活以外的原因触发;
  • Sec-Fetch-Dest:请求的目的,表示客户端希望获取什么样的资源。
  • Accept-Encoding:接受的编码方式。
  • Accept-Language:接受的语言。

请求体

POST和PUT方法包含请求体,本实验中是GET请求,不包含请求体。

响应报文

HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Last-Modified: Thu, 27 Oct 2022 02:34:23 GMT\r\n
Accept-Ranges: bytes\r\n
ETag: "b7e928a0ace9d81:0"\r\n
Server: Microsoft-IIS/10.0\r\n
Date: Thu, 27 Oct 2022 02:34:43 GMT\r\n
Content-Length: 1631\r\n
\r\n
[HTTP response 1/2]
[Time since request: 0.003017000 seconds]
[Request in frame: 5]
[Next request in frame: 29]
[Next response in frame: 31]
[Request URI: http://127.0.0.1/favicon.ico]
File Data: 1631 bytes

由于C++ socket编程的响应报文是我自己编写的,内容比较简单,不够完整,因此在这里分析使用IIS搭建的服务器发送的响应报文。

响应行

  • http版本:在本实验中,是HTTP/1.1,必须和请求报文的协议版本匹配。
  • 状态码和解释:表示请求的结果。
    • 200 OK:请求成功;
    • 301 Moved Permanently:请求的对象被移走,新的位置在响应中通过Location: 给出;
    • 400 Bad Request:服务器不能解释请求报文;
    • 404 Not Found:服务器中找不到请求的文档;
    • 505 HTTP Version Not Supported:服务器不支持相应的HTTP版本。

响应头

  • Date:发送响应报文的时间。
  • Server:服务器的版本和平台。
  • Last-Modified:最近一次修改的时间。
  • ETag:被请求变量的实体值,是一个可以与Web资源关联的记号。
  • Accept-Ranges:服务器支持的可用于定义范围的单位。
  • Content-Length:响应体的长度。
  • Keep-Alive:TCP通道可以保持的时间和最多接受的请求次数。
  • Connection:连接方式,同上。
  • Content-Type:响应体的内容类型和编码方式。

响应体

本实验中,响应体就是我编写的html文件,在次不再赘述。

四次挥手

IIS服务器捕获的四次挥手:

web配置界面,服务器,前端,交互

C++ socket编程捕获的四次挥手:

web配置界面,服务器,前端,交互

  1. A向B发送FIN, ACK报文,请求终止连接。
  2. B收到A发送的FIN, ACK报文后,回复ACK报文,表示确认收到了终止连接的请求。
  3. B向A发送FIN, ACK报文,请求终止连接。
  4. A收到B发送的FIN, ACK报文后,回复ACK报文,表示确认收到了终止连接的请求,双方正式终止连接。

客户端和服务器都可以主动发起挥手动作。在IIS服务器捕获时四次挥手非常标准,我关闭了浏览器,由客户端先向服务器发送终止连接的请求。

但在C++ socket编程捕获的文件中, 只能看到三次挥手,但是观察Seq和Ack的值和连接的过程,一切正常。查阅相关资料后分析,这是因为我的服务器是通过socket编程实现的,发送完响应报文之后,调用close函数时就会向客户端发送终止连接的请求,这一步并不会在捕获文件中体现。之后客户端(64400)回复ACK报文确认收到了终止连接的请求也印证了这一点。

实验中遇到的问题及分析

  1. 在使用C++搭建简单的web服务器时,由于对html的了解不够深刻,发送的响应报文不正确,一直无法正常打开网页。经过分析发现两个问题:第一,发现Content-length一定要和消息体(html文件)的长度一致,否则无法正确显示;第二,发送响应报文,发送的消息长度必须和实际的一致,太长了会读入乱码。虽然能够顺利完成实验,但是这个程序只是一个很简单的web服务器,没有对请求报文进行解析,响应报文也只有一种情况。希望后续能够在对http协议学习更深入的基础上编写一个完整的web服务器。
  2. 在编写web界面时,由于对于html语言了解不够深刻,出现了很多语法错误,也难以实现想要的效果。经过对html语言的初步学习后,能够实现预期的界面。但是这只是一个很简单的个人主页,希望以后能够改进。
  3. 在使用Wireshark捕获交互过程时,一开始对于软件不够熟悉,不清楚如何使用。后来可以正常捕获,但是捕获的内容很多,经过学习我发现可以使用过滤条件,就能快速定位到我们需要的交互过程。
  4. 在IIS服务器捕获的文件中,一开始我看到的响应报文总是304 Not Modified,但是依然能正常打开网页。后来发现是因为网页有缓存机制,如果第一次连接之后,html文件没有改变,就不会重新返回200 OK的响应报文。因此,我稍微修改了一下html文件,就成功捕获到了200 OK的响应报文。
  5. 在C++ socket编程捕获的文件中,我只观察到三次挥手,但是观察Seq和Ack的值和连接的过程,一切正常。查阅相关资料后分析,这是因为我的服务器是通过socket编程实现的,发送完响应报文之后,调用close函数时就会向客户端发送终止连接的请求,这一步并不会在捕获文件中体现。

参考资料

Sec-Fetch-*请求头,了解下? - 福禄网络研发团队 - 博客园

使用 WireShark 分析 TCP/IP 三次握手 和 四次挥手 - bylijian - 博客园文章来源地址https://www.toymoban.com/news/detail-716008.html

到了这里,关于配置web服务器+编写简单页面+分析交互过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Web端服务器推送技术原理分析及dwr框架简单的使用,html5移动web开发

    缺点  : a) 糟糕的用户体验 b) 对服务器的压力很大,并且造成带宽的极大浪费。 2.2 Ajax 轮询 Ajax隔一段时间(通常使用JavaScript的setTimeout函数)就去服务器查询是否有改变,从而进行增量式的更新。但是间隔多长时间去查询成了问题,因为性能和即时性造成了严重的反比

    2024年04月16日
    浏览(52)
  • 中文大语言模型 Llama-2 7B(或13B) 本地化部署 (国内云服务器、GPU单卡16GB、中文模型、WEB页面TextUI、简单入门)

            本文目的是让大家先熟悉模型的部署,简单入门;所以只需要很小的算力,单台服务器 单GPU显卡(显存不低于12GB),操作系统需要安装 Ubuntu 18.04。         准备一台服务器 单张英伟达GPU显卡(显存不低于12GB),操作系统需要安装 Ubuntu 18.04 (具体安装过程忽略)

    2024年02月08日
    浏览(48)
  • 使用Go语言编写简单的HTTP服务器

    在Go语言中,我们可以使用标准库中的\\\"net/http\\\"包来编写HTTP服务器。下面是一个简单的示例,展示了如何使用Go编写一个基本的HTTP服务器。 go 复制代码 package  main import  ( \\\"fmt\\\"   \\\"net/http\\\"   ) func   main ()  { // 创建一个处理器函数,处理所有对根路径的请求 handler := func (w http.

    2024年01月24日
    浏览(51)
  • HTTP 错误 401.3 - Unauthorized 由于 Web 服务器上此资源的访问控制列表(ACL)配置或加密设置,您无权查看此目录或页面。

    用IIS 发布网站,不能访问且出现错误:HTTP 错误 401.3 - Unauthorized 由于Web服务器上此资源的访问控制列表(ACL)配置或加密设置。您无权查看此目录或页面 问题截图: 问题描述:HTTP 错误 401.3 - 未经授权:访问由于 ACL 对所请求资源的设置被拒绝。 原因分析:IIS匿名用户一般属于

    2024年02月05日
    浏览(51)
  • 阿里云服务器+宝塔 (尝试部署一个最简单的静态页面)

    进入网址:服务器购买地址 选择预装宝塔面板 购买完成后前往控制台 查看当前实例 设置或修改密码 设置用户名和密码 输入用户名和密码 连接成功页面如下: 请看客老爷移步到这个文章,传送门🙈 在命令行中输入: bt default 这里可以显示访问地址和密码,如图。 直接复

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

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

    2024年02月13日
    浏览(43)
  • 简单Web服务器程序设计与实现

    实现提供静态网页服务的web服务器 实现提供cgi动态网页服务的web服务器 web服务器实现多进程服务 Linux程序设计综合实践是我们软件工程专业必须经历的过程,是理论与实践相结合的重要方式,使我们在实践中了解Linux操作系统、在实践中巩固知识。实习是个人综合能力的检验

    2024年02月08日
    浏览(45)
  • tomcat服务器统一配置错误页面

    问题:访问服务器出错时,可能页面会显示空白或者别的错误页面,这样的显示并不友好,所以我们要统一解决一下这样不友好的页面 解决方法 :将所有异常都抛出,最后抛给tomcat服务器进行统一的处理。 步骤一:编写服务器500错误或者404错误页面;例如:error404.jsp 步骤二

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

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

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

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

    2024年03月16日
    浏览(45)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包