精华内容
下载资源
问答
  • web服务器工作原理
    千次阅读
    2019-04-01 13:35:52

    1.1.2. Web服务器工作原理

    HTTP协议基于TCP协议上,是一个应用层协议,用于用户代理和Web服务器进行通信。Web服务器通常采用一问一答的方式进行工作:

    1. 在用户代理上用户发起资源请求,请求内容包括但不限于:指定资源的唯一标识URI,指明动作类型(GET/POST/DELETE/PUT...)
    2. 用户代理解析用户输入URI并从中获取目标域名,交由DNS服务器解析。如果URI中指定某IP地址,这无需这步。
    3. 如果与服务器的会话还没建立,此时先建立TCP连接,并完成HTTP协商(确定双方均可接受的处理方式,包括协议版本,是否加密,内容格式等等)。
    4. 用户代理把请求内容封装成HTTP数据包向服务器发送。
    5. 服务器接收到资源请求并以之前协商好的方式解包并处理。
    6. 服务器请求的资源封装成HTTP数据包并返回给用户代理。
    更多相关内容
  • 1. 简述HTTP协议的内容,包含请求协议和返回协议。 2. 验证简单WEB服务器的实现原理,分析主要的代码实现,并总结WEB服务器处理客户端请求的全过程。
  • Web服务器工作原理详解(基础篇)

    万次阅读 多人点赞 2018-08-14 17:12:00
    概述:Web服务器概念较为广泛,我们最常说的Web服务器指的是网站服务器,它是建立在Internet之上并且驻留在某种计算机上的程序。Web服务器可以向Web客户端(如浏览器)提供文档或其他服务,只要是遵循HTTP协议而设计的...

    概述:Web服务器概念较为广泛,我们最常说的Web服务器指的是网站服务器,它是建立在Internet之上并且驻留在某种计算机上的程序。Web服务器可以向Web客户端(如浏览器)提供文档或其他服务,只要是遵循HTTP协议而设计的网络应用程序都可以是Web客户端。

    Web服务器和HTTP服务器可以说是同一个东西,当然非得细分的话,HTTP服务器是建立在HTTP协议之上的提供文档浏览的服务器,更多的是提供静态的文件。而Web服务器涵盖了HTTP服务器(这一点可以自行百度百科), Web服务器不仅能够存储信息,还能在用户通过Web浏览器提供的信息的基础上运行脚本和程序。
    Web服务器 约等于 HTTP服务器 + 其他服务

    目前所熟知的Web服务器有很多,其最主流的是 Apache, Nginx, IIS
    各大Web服务器的实现细节都不同,是为了某种情形而设计开发的。但是它们的基础工作原理是相同的,这也是本次基础篇所讲解的内容。

    一、Web服务器工作原理图解

    这里写图片描述
    首先我们暂时不考虑HTTP协议的各种请求方式,我们先跟着**(Web服务器工作原理总体描述01)这张图,将一次Web服务的工作流程过一遍,我们假设以浏览器作为客户端
    (1) 用户做出了一个操作,可以是填写网址敲回车,可以是点击链接,可以是点击按键等,接着浏览器获取了该事件。
    (2) 浏览器与对端服务程序建立TCP连接。
    (3) 浏览器将用户的事件
    按照HTTP协议格式**打包成一个数据包,其实质就是在待发送缓冲区中的一段有着HTTP协议格式的字节流。
    (4) 浏览器确认对端可写,并将该数据包推入Internet,该包经过网络最终递交到对端服务程序。
    (5) 服务端程序拿到该数据包后,同样以HTTP协议格式解包,然后解析客户端的意图。
    (6) 得知客户端意图后,进行分类处理,或是提供某种文件、或是处理数据。
    (7) 将结果装入缓冲区,或是HTML文件、或是一张图片等。
    (8) 按照HTTP协议格式将(7)中的数据打包
    (9) 服务器确认对端可写,并将该数据包推入Internet,该包经过网络最终递交到客户端。
    (10) 浏览器拿到包后,以HTTP协议格式解包,然后解析数据,假设是HTML文件。
    (11) 浏览器将HTML文件展示在页面
    以上为Web服务器工作基本原理。其实不难发现,这仅仅只是一个简单的网络通信。我们应该深信,作为一个服务器,其根本的工作无非有三个

    1. 接收数据 2. 发送数据 3. 数据处理
      而Web服务器的本质就是 接收数据 ⇒ HTTP解析 ⇒ 逻辑处理 ⇒ HTTP封包 ⇒ 发送数据
      高级的服务器无非就是将这三个部分更加细致的设计了。

    二、Web服务器之提供静态文件工作原理图解

    Web服务器最主要的功能是提供静态的文件。日常的上网浏览大多是网页浏览,少数时候才会有一些数据的提交操作。因此,我们结合上一张图示来重点讲解在GET请求下的Web服务器工作原理。
    这里写图片描述
    其他流程基本不变,着重在于红色与蓝色部分。
    (1) 当用户点击一个网页链接或浏览器加载一些资源(css,jpg …)时产生。
    (6) 服务程序解包后,确定其为GET请求,并且是对该服务器上的某一资源的请求。首先服务程序会去确认该路径是否存在,再确定该路径的文件是否可以获取。
    (7-1) 如果请求的路径有误,或者该资源不能被用户获取,则返回错误提示页面。很多服务器的错误页面只有404,更专业的应该是将错误分类并返回对应的错误代码页面。
    (7-2) 如果该路径合法且文件可以被获取,那么服务程序将根据该文件类型进行不同的装载过程,记录其类型作为(8)中HTTP协议中对应的返回类型,并加入响应头。

    假设以点击一个页面链接为例,浏览器首先将HTML文件请求过来,再以同样的流程对HTML文件中包含的资源文件路径进行依次请求。
    这里写图片描述

    三、Web服务器之数据提交工作原理图解

    仅仅只是网页的浏览并不能满足所有人的需求,客户端与服务器应当是有数据交互的。
    即使单方面的资源请求任然是网络的主力军。
    我们应该清楚的知道,数据提交对于用户来说有什么作用。
    (1) 资源上传 (2) 登陆验证 (3) API接口调用 (4) 远程指令等
    数据提交使得用户的操作性有了质的飞跃,它使得HTTP短连接获取静态文件的方式提升到了动态交互的层次上。该性质也催化出各式各样的编程语言、框架。例如PHP,JavaWeb。
    如果你留意目前主流的那些大型服务器,你会发现再高级再牛逼的东西实际是也是最基础的东西建造的。那么我们还可以顺便学习一下最古老的动态技术CGI
    这里写图片描述
    其他流程基本不变,着重在于红色与蓝色部分。
    (1) 用户提交数据,假设用户点击一个按键提交填好的信息。在(3)中将以POST格式写入,并填入提交至服务端的可执行程序的路径。
    (6) 服务端将参数与该CGI绑定,复制进程,用管道传递参数和接收结果
    (7) 子进程执行CGI,接收(6)父进程传来的参数,运算完成返回结果。
    最后父进程将结果装入静态模板文件,放入缓冲区

    四、动态技术

    我们得明白,Web服务器是以短连接为主,并且获取的数据到达浏览器的那一刻一定是静态的不变的。那么所谓动态实际是指两种情况

    1. 服务端产生
      (1) 用户POST提交数据到某个程序,程序根据该数据作为参数运行,得出结果并装入静态的模板页面中,返回该静态页面。但对于用户来说,同一个页面,做了一个操作后数据不一样了。好了,这就是动态页面。(CGI原理)
      (2) PHP的原理是,用户GET请求一个php后缀的文件,服务器先执行该php后缀文件中的PHP代码,将结果填入代码的位置,再返回。当然也可以提交数据参与运算再返回。
    2. 客户端产生
      (1) 用户GET请求一个JavaScript文件,服务端不做任何运算返回该静态文件。浏览器收到该JS文件,在本地执行并更新页面。
      (2) 用户POST提交数据到服务端,服务端根据该提交的数据指令返回静态文件,浏览器收到后执行并更新。
    展开全文
  • web服务器工作原理

    千次阅读 2020-01-10 10:15:18
    Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以向浏览器等Web客户端提供文档,也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。 一、web服务器与http服务器区别 Web...

    本文参考https://blog.csdn.net/qq_36359022/article/details/81666221

    Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以向浏览器等Web客户端提供文档,也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。

    一、web服务器与http服务器区别

    Web服务器是指驻留于因特网上某种类型计算机的程序。当Web浏览器(客户端)连到服务器上并请求文件时,服务器将处理该请求并将文件反馈到该浏览器上,附带的信息会告诉浏览器如何查看该文件(即文件类型)。服务器使用HTTP(超文本传输协议)与客户机浏览器进行信息交流,这就是人们常把它们称为HTTP服务器的原因。
    Web服务器不仅能够存储信息,还能在用户通过Web浏览器提供的信息的基础上运行脚本和程序。

    Web服务器 约等于 HTTP服务器 + 其他服务

    目前所熟知的Web服务器有很多,其最主流的是 Apache, Nginx, IIS

    GET和POST是HTTP请求的两种基本方法:
    对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
    而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

    二、web服务器工作原理
    在这里插入图片描述
    工作流程:
    (1)用户做出操作,可以是填写网址敲回车、可以是点击链接、可以是点击按键等,接着浏览器获取该事件。
    (2)浏览器与对端服务程序建立TCP连接(三次握手)
    (3)浏览器将用户事件按照HTTP协议格式打包成一个数据包,其实质就是在待发送缓冲区中的一段有着HTTP协议格式的字节流。
    (4)浏览器确认对端可写,并将该数据包推入Internet,该包经过网络最终递交到对端服务程序。
    (5)服务端程序拿到该数据包后,同样以HTTP协议格式解包,然后解析客户端的意图。
    (6)得知客户端意图后,进行分类处理,或是提供某种文件、或是处理数据。
    (7)将结果装入缓冲区,或是HTML文件、或是一张图片
    (8)按照HTTP协议格式将(7)中的数据打包
    (9)服务器确认对端可写,并将该数据包推入Internet,该包经过网络最终递交到客户端
    (10)浏览器拿到包后,以HTTP协议格式解包,然后解析数据,假设是HTML文件
    (11)浏览器将HTML文件显示在页面

    而Web服务器的本质就是 接收数据 ⇒ HTTP解析 ⇒ 逻辑处理 ⇒ HTTP封包 ⇒ 发送数据

    三、Web服务器之提供静态文件

    Web服务器最主要的功能是提供静态的文件。日常的上网浏览大多是网页浏览,少数时候才会有一些数据的提交操作
    在这里插入图片描述
    四、Web服务器之数据提交
    仅仅只是网页的浏览并不能满足所有人的需求,客户端与服务器应当是有数据交互的。
    即使单方面的资源请求任然是网络的主力军。
    在这里插入图片描述

    公共网关接口(Common Gateway Interface,CGI)是Web 服务器运行时外部程序的规范,按CGI编写的程序可以扩展服务器功能。CGI应用程序能与浏览器进行交互,还可通过数据API与数据库服务器等外部数据源进行通信,从数据库服务器中获取数据。格式化为HTML文档后,发送给浏览器,也可以将从浏览器获得的数据放到数据库中。几乎所有服务器都支持CGI,可用任何语言编写CGI,包括流行的C、C++、Java、VB 和Delphi 等。

    展开全文
  • Web服务器工作原理.docxWeb服务器的工作原理.docxWeb服务器的工作原理.docxWeb服务器的工作原理.docxWeb服务器的工作原理.docxWeb服务器的工作原理.docxWeb服务器的工作原理.docxWeb服务器的工作原理.docx
  • web服务器运行原理

    千次阅读 2019-03-04 09:45:41
    这几天的工作,就是把程序解耦,将功能分离,服务器只用来提供WEB服务,WEB应用用来实现数据处理。 大家可以了解一下开发中比较常用的WEB框架,比如 Apache ,Nigix,Tomcat等。 没有一个服务器框架安装完成后,就...

    3.1.1 HTTP 服务器运行原理

    在这里插入图片描述
    之前在实现的程序中,主要代码都实现在上图的左半部分。

    服务器的运行和 WEB 应用的处理,都是在一个文件中实现的。

    这几天的工作,就是把程序解耦,将功能分离,服务器只用来提供WEB服务,WEB应用用来实现数据处理。

    大家可以了解一下开发中比较常用的WEB框架,比如 Apache ,Nigix,Tomcat等。

    没有一个服务器框架安装完成后,就完成了WEB应用的开发的。

    因为服务器根本不知道你要完成的功能是什么,所以只提供给你服务,而应用的功能按照服务的接口来完成。然后让服务器响应处理。

    3.1.2 原始服务器回顾分析

    在前面的课程中,我们实现过一个 HTTP 服务器,我们就在这个服务器的基础上,来实现这阶段的 MiniWEB 框架。

    首先,先来回顾一下这个HTTP服务器的代码

    注意:将代码复制到工程文件中之后,还需要将资源文件复制到工程目录中

    资源文件所在路径
    在这里插入图片描述
    在这里插入图片描述
    原始服务器 WebServer.py

    #   代码实现:
        import socket
        import re
        import multiprocessing
    
    
        def service_client(new_socket):
            """为客户端返回数据"""
    
            # 1. 接收浏览器发送过来的请求 ,即http请求相关信息
            # GET / HTTP/1.1
            # .....
            request = new_socket.recv(1024).decode("utf-8")
            #将请求头信息进行按行分解存到列表中
            request_lines = request.splitlines()
            # GET /index.html HTTP/1.1
            file_name = ""
            #正则:  [^/]+ 不以/开头的至少一个字符 匹配到/之前
            #      (/[^ ]*) 以分组来匹配第一个字符是/,然后不以空格开始的0到多个字符,也就是空格之前
            #      最后通过匹配可以拿到 请求的路径名  比如:index.html
            ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])
            #如果匹配结果 不为none,说明请求地址正确
            if ret:
                #利用分组得到请求地址的文件名,正则的分组从索引1开始
                file_name = ret.group(1)
                print('FileName:  ' + file_name)
                #如果请求地址为 / 将文件名设置为index.html,也就是默认访问首页
                if file_name == "/":
                    file_name = "/index.html"
    
            # 2. 返回http格式的数据,给浏览器
            try:
                #拼接路径,在当前的html目录下找访问的路径对应的文件进行读取
                f = open("./html" + file_name, "rb")
            except:
                #如果没找到,拼接响应信息并返回信息
                response = "HTTP/1.1 404 NOT FOUND\r\n"
                response += "\r\n"
                response += "------file not found-----"
                new_socket.send(response.encode("utf-8"))
            else:
                #如果找到对应文件就读取并返回内容
                html_content = f.read()
                f.close()
                # 2.1 准备发送给浏览器的数据---header
                response = "HTTP/1.1 200 OK\r\n"
                response += "\r\n"
                #如果想在响应体中直接发送文件内的信息,那么在上面读取文件时就不能用rb模式,只能使用r模式,所以下面将响应头和响应体分开发送
                #response += html_content
                # 2.2 准备发送给浏览器的数据
                # 将response header发送给浏览器
                new_socket.send(response.encode("utf-8"))
                # 将response body发送给浏览器
                new_socket.send(html_content)
    
            # 关闭套接
            new_socket.close()
    
        def main():
            """用来完成整体的控制"""
            # 1. 创建套接字
            tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            #用来重新启用占用的端口
            tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    
            # 2. 绑定IP和端口号
            tcp_server_socket.bind(("", 7890))
    
            # 3. 设置套接字监听连接数(最大连接数)
            tcp_server_socket.listen(128)
    
            while True:
                # 4. 等待新客户端的链接
                new_socket, client_addr = tcp_server_socket.accept()
    
                # 5. 为连接上来的客户端去创建一个新的进程去运行
                p = multiprocessing.Process(target=service_client, args=(new_socket,))
                p.start()
                #因为新进程在创建过程中会完全复制父进程的运行环境,所以父线程中关闭的只是自己环境中的套接字对象
                #而新进程中因为被复制的环境中是独立存在的,所以不会受到影响
                new_socket.close()
    
            # 关闭监听套接字
            tcp_server_socket.close()
    
        if __name__ == "__main__":
            main()
    

    3.1.3 程序解耦

    概念理解 什么是耦合关系? 耦合关系是指某两个事物之间如果存在一种相互作用、相互影响的关系,那么这种关系就称"耦合关系"。 在软件工程中的耦合就是代码之间的依赖性。 代码之间的耦合度越高,维护成本越高,导致牵一发会动全身。因此程序设计应使代码之间的耦合度最小。 代码开发原则之一:高内聚,低耦合。 这句话的意思就是程序的每一个功能都要单独内聚在一个函数中,让代码之间的耦合度达到最小。也就是相互之间的依赖性达到最小。

    实现面向对象的思想的代码重构 以面向对象的思想来完成服务器的代码实现 实现过程:

    1.封装类
    2.初始化方法中创建socket对象
    3.启动服务器的方法中进行服务监听
    4.实现数据处理的方法
    5.对象属性的相应修改
    6.重新实现main方法,创建WEBServer类对象并启动服务
    WebServer.py

     # 面向对象修改数据
        import socket
        import re
        import multiprocessing
    
    
        class WEBServer(object):
            #在初始化方法中完成服务器Socket对象的创建
            def __init__(self):
                """用来完成整体的控制"""
                # 1. 创建套接字
                self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                # 用来重新启用占用的端口
                self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    
                # 2. 绑定IP和端口号
                self.tcp_server_socket.bind(("", 7890))
    
                # 3. 设置套接字监听连接数(最大连接数)
                self.tcp_server_socket.listen(128)
    
    
            def service_client(self,new_socket):
                """为这个客户端返回数据"""
    
                # 1. 接收浏览器发送过来的请求 ,即http请求相关信息
                # GET / HTTP/1.1
                # .....
                request = new_socket.recv(1024).decode("utf-8")
                #将请求头信息进行按行分解存到列表中
                request_lines = request.splitlines()
                # GET /index.html HTTP/1.1
                # get post put del
                file_name = ""
                #正则:  [^/]+ 不以/开头的至少一个字符 匹配到/之前
                #      (/[^ ]*) 以分组来匹配第一个字符是/,然后不以空格开始的0到多个字符,也就是空格之前
                #      最后通过匹配可以拿到 请求的路径名  比如:index.html
                ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])
                #如果匹配结果 不为none,说明请求地址正确
                if ret:
                    #利用分组得到请求地址的文件名,正则的分组从索引1开始
                    file_name = ret.group(1)
                    print('FileName:  ' + file_name)
                    #如果请求地址为 / 将文件名设置为index.html,也就是默认访问首页
                    if file_name == "/":
                        file_name = "/index.html"
    
                # 2. 返回http格式的数据,给浏览器
                try:
                    #拼接路径,在当前的html目录下找访问的路径对应的文件进行读取
                    f = open("./html" + file_name, "rb")
                except:
                    #如果没找到,拼接响应信息并返回信息
                    response = "HTTP/1.1 404 NOT FOUND\r\n"
                    response += "\r\n"
                    response += "------file not found-----"
                    new_socket.send(response.encode("utf-8"))
                else:
                    #如果找到对应文件就读取并返回内容
                    html_content = f.read()
                    f.close()
                    # 2.1 准备发送给浏览器的数据---header
                    response = "HTTP/1.1 200 OK\r\n"
                    response += "\r\n"
                    #如果想在响应体中直接发送文件内的信息,那么在上面读取文件时就不能用rb模式,只能使用r模式,所以下面将响应头和响应体分开发送
                    #response += html_content
                    # 2.2 准备发送给浏览器的数据
                    # 将response header发送给浏览器
                    new_socket.send(response.encode("utf-8"))
                    # 将response body发送给浏览器
                    new_socket.send(html_content)
    
                # 关闭套接
                new_socket.close()
    
    
    
    
            def run(self):
                while True:
                    # 4. 等待新客户端的链接
                    new_socket, client_addr = self.tcp_server_socket.accept()
    
                    # 5. 为这个客户端服务
                    p = multiprocessing.Process(target=self.service_client, args=(new_socket,))
                    p.start()
                    #因为新线程在创建过程中会完全复制父线程的运行环境,所以父线程中关闭的只是自己环境中的套接字对象
                    #而新线程中因为被复制的环境中是独立存在的,所以不会受到影响
                    new_socket.close()
    
                # 关闭监听套接字
                self.tcp_server_socket.close()
    
        def main():
            webServer = WEBServer()
            webServer.run()
    
        if __name__ == "__main__":
            main()
    

    通过使用面向对象的思想,将代码重构后,耦合性降低,但还没有完全实现功能的分离。 目前还是在一个文件中实现所有的程序功能,也就是说,目前只是完成了在原理图中,左半侧的功能。后面会继续改进。

    3.1.4 区分动态数据和静态数据

    静态数据:是指在页面进行访问时,无论何时访问,得到的内容都是同样的,不会发生任意变化(比如我们现在实现的API网页的访问效果,这些API文件都是保存在本地(或服务器上)的一些固定的文档说明,无论在何时何地访问这些数据,都是相同的,不会发生变化)

    动态数据:是指在页面进行访问时,得到的数据是经过服务器进行计算,加工,处理过后的数据,称为动态数据,哪怕只是加了一个空格

    比如:实时新闻,股票信息,购物网站显示的商品信息等等都动态数据

    在这部分代码实现中,先来实现不同形式的页面访问,服务器返回不同的数据(数据暂时还是静态的,假的数据,真正的动态数据会在完成框架后,在数据库中读取返回)

    这里设定: xxx.html 访问时,返回的是静态数据 API 文档中的内容, xxx.py 访问时,返回的是动态数据(数据先以静态数据代替)

    实现过程: 1.先根据访问页面地址判断访问数据的类型,是py的动态还是html的静态 2.根据动态请求的路径名的不同来返回不同的数据,不在使用html获取数据,而使用py来获取

    WebServer.py

     # ...
        # 前面的代码不需要修改
                if ret:
                #利用分组得到请求地址的文件名,正则的分组从索引1开始
                file_name = ret.group(1)
                print('FileName:  ' + file_name)
                #如果请求地址为 / 将文件名设置为index.html,也就是默认访问首页
                if file_name == "/":
                    file_name = "/index.html"
                # ------------- 这里开始修改代码------------
                #判断访问路径的类型
                if file_name.endswith('.py'):
    
                    #根据不同的文件名来确定返回的响应信息
                    if file_name == '/index.py':                #首页
                        header =  "HTTP/1.1 200 OK\r\n"         #响应头
                        body = 'Index Page ...'                 #响应体
                        data = header + '\r\n' + body           #拼接响应信息
                        new_socket.send(data.encode('utf-8'))   #返回响应信息
                    elif file_name == '/center.py':             #个人中心页面
                        header =  "HTTP/1.1 200 OK\r\n"
                        body = 'Center Page ...'
                        data = header + '\r\n' + body
                        new_socket.send(data.encode('utf-8'))
                    else:                                       #其它页面
                        header =  "HTTP/1.1 200 OK\r\n"
                        body = 'Other Page ...'
                        data = header + '\r\n' + body
                        new_socket.send(data.encode('utf-8'))
                else:
                    # 2. 返回http格式的数据,给浏览器
                    try:
                        #拼接路径,在当前的html目录下找访问的路径对应的文件进行读取
                        f = open("./html" + file_name, "rb")
                    except:
                        #如果没找到,拼接响应信息并返回信息
                        response = "HTTP/1.1 404 NOT FOUND\r\n"
                        response += "\r\n"
                        response += "------file not found-----"
                        new_socket.send(response.encode("utf-8"))
                    else:
                        #如果找到对应文件就读取并返回内容
                        html_content = f.read()
                        f.close()
                        # 2.1 准备发送给浏览器的数据---header
                        response = "HTTP/1.1 200 OK\r\n"
                        response += "\r\n"
                        #如果想在响应体中直接发送文件内的信息,那么在上面读取文件时就不能用rb模式,只能使用r模式,所以下面将响应头和响应体分开发送
                        #response += html_content
                        # 2.2 准备发送给浏览器的数据
                        # 将response header发送给浏览器
                        new_socket.send(response.encode("utf-8"))
                        # 将response body发送给浏览器
                        new_socket.send(html_content)
    

    3.1.5 实现动态数据的响应优化

    虽然前面的代码实现了设计需求,但是实现过程太过冗余,不符合代码开发原则。 一个服务器中提供可以访问的页面肯定不止这么几个,如果每一个都实现一次响应信息的编写,那冗余代码就太多了,不符合代码的开发规范 通过分析我们可以看出,代码中大部分内容都是相同的,只有在响应信息的响应体部分不同,那么就可以将代码优化一下。

    实现过程: 因为所有页面的响应信息都是相同的,所以让这些页面共用一块代码

    1. 将响应头和空行代码放到判断页面之前
    2. 将发拼接和发送代码放到判断之后
    3. 页面判断中,只根据不同的页面设计不同的响应体信息
      实现代码: WebServer.py
     # ...
        # 前面的代码不需要修改
    
            #判断访问路径的类型
            # ------------- 这里开始修改代码------------ 
            if file_name.endswith('.py'):
    
                header = "HTTP/1.1 200 OK\r\n"  # 响应头
                #根本不同的文件名来确定返回的响应信息
                if file_name == '/index.py':
                    body = 'Index Page ...'                 #响应体
                elif file_name == '/center.py':
                    body = 'Center Page ...'
                else:
                    body = 'Other Page ...'
                data = header + '\r\n' + body  # 拼接响应信息
                new_socket.send(data.encode('utf-8'))  # 返回响应信息
    
            # ------------- 这里开始修改代码结束------------
            else:
            # 后面的代码不需要修改
    

    3.1.6 实现功能的分离

    代码被进一步优化,但是还是存在问题。网络请求和数据处理还是没有分开,还是在同一个文件中实现的。

    实际开发中WEB服务器有很多种,比如Apache,Nigix等等。

    如果在开发过程中,需要对 WEB 服务器进行更换。那么我们现在的做法就要花费很大的精力,因为 WEB 服务和数据处理都在一起。

    如果能将程序的功能进行进行分离,提供 WEB 请求响应的服务器只管请求的响应,而响应返回的数据由另外的程序来进行处理。

    这样的话,WEB 服务和数据处理之间的耦合性就降低了,这样更便于功能的扩展和维护

    比如:

    一台电脑,如果要是所有的更件都是集成在主板上的,那么只要有一个地方坏了。那整个主板都要换掉。成本很高

    如果所有的硬件都是以卡槽接口的形式插在主板上,那么如果哪一个硬件坏了或要进行升级扩展都会很方便,降低了成本。

    在实际开发过程中,代码的模块化思想就是来源于生活,让每个功能各司其职。

    实现思想: 将原来的服务器文件拆分成两个文件,一个负责请求响应,一个负责数据处理。 那么这里出现一个新的问题,两个文件中如何进行通信呢?负责数据处理的文件怎么知道客户端要请求什么数据呢?

    想一下主板和内存之间是如何连接的?

    实现过程: 1.WebServer 文件只用来提供请求的接收和响应 2.WebFrame 文件只用来提供请求数据的处理和返回 3.文件之间利用一个函数来传递请求数据和返回的信息

    实现代码 WebServer.py

     ------------- 这里需要修改代码------------ 
        # 因为在这里需要使用框架文件来处理数据,所以需要进行模块导入
        import WebFrame
    
    
        #...
        # 前面的代码不需要修改
        # ------------- 这里开始修改代码------------ 
        #判断访问路径的类型
        if file_name.endswith('.py'):
    
            header = "HTTP/1.1 200 OK\r\n"  # 响应头
            # 根本不同的访问路径名来向框架文件获取对应的数据
            # 通过框架文件中定义的函数将访问路径传递给框架文件
            body = WebFrame.application(file_name)
            #将返回的数据进行拼接
            data = header + '\r\n' + body  # 拼接响应信息
            new_socket.send(data.encode('utf-8'))  # 返回响应信息
    
        # ------------- 这里开始修改代码结束------------
        else:
            # 后面的代码不需要修改
            # ...
    

    WebFrame.py

    # 在框架文件中,实现一个函数,做为 Web 服务器和框架文件之间的通信接口
    # 在这个接口函数中,根据 Web 服务器传递过来的访问路径,判断返回的数据
    def application(url_path):
        if url_path == '/index.py':
            body = 'Index Page ...'                 #响应体
        elif url_path == '/center.py':
            body = 'Center Page ...'
        else:
            body = 'Other Page ...'
        return body
    

    代码实现到这里,基本将功能进行了分离,初步完成了前面原理图中的功能分离。

    但是还没有真正的完成框架,到这里只是完成了框架中的一小步。

    3.1.7 WSGI

    WSGI是什么? WSGI,全称 Web Server Gateway Interface,是为 Python 语言定义的 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。

    用来描述web server如何与web application通信的规范。

    实际上,WSGI协议中,定义的接口函数就是 application ,定义如下:

    
    def application(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html')])
        return [b'<h1>Hello, web!</h1>']
    

    这个函数有两个参数: 参数一: web服务器向数据处理文件中传递请求相关的信息,一般为请求地址,请求方式等,传入类型约定使用字典 参数二: 传入一个函数,使用函数回调的形式,将数据处理的状态结果返回给服务器,服务器的函数一般用来存储返回的信息,用来组合响应头信息 返回值: 用来返回具体的响应体数据.

    服务器和框架应用程序在共同遵守了这个协议后,就可以通过 application 函数进行通信。完成请求的转发和响应数据的处理返回。

    实现过程: 1.在服务器中调用application函数 2.定义用来储存返回的响应头信息的回调函数,函数有两个参数,一个是状态,一个是其它信息,以字典形式传入 3.以字典传入请求地址名,传入回调的函数名 4.当处理完数据 后,调用传入的函数并返回数据 5.服务器收到返回的信息后进行响应信息的拼接处理.

    代码实现: WebServer.py

         import WebFrame
    
    
            #...
            # 前面的代码不需要修改
            # ------------- 这里开始修改代码------------ 
            #判断访问路径的类型
            if file_name.endswith('.py'):
                #要先调用这个函数,如果不调用,那么回调函数不能执行,下面拼接数据就会出错
                #根本不同的文件名来向数据处理文件获取对应的数据
                #并将回调函数传入进去
                env = {'PATH_INFO':file_name}
                body = WEBFrame.application(env,self.start_response)
    
                #拼接返回的状态信息
                header = "HTTP/1.1 %s\r\n"%self.status  # 响应头
                #拼接返回的响应头信息
                #因是返回是以列表装元组的形式返回,所以遍历列表,然后拼接元组里的信息
                for t in self.params:
                    header += '%s:%s\r\n'%t
    
                data = header + '\r\n' + body  # 拼接响应信息
                new_socket.send(data.encode('utf-8'))  # 返回响应信息
    
            # ------------- 这里开始修改代码结束------------
            else:
                # 后面的代码不需要修改
                # ...
    
        # ------------- 这里需要修改代码------------ 
        #定义一个成员函数 ,用来回调保存数据使用
        def start_response(self,status,params):
            #保存返回回来的响应状态和其它响应信息
            self.status = status
            self.params = params
    
    

    WebFrame.py

    # 实现 WSGI 协议中的 application 接口方法
    def application(environ, start_response):
        # 从服务器传过来的字典中将访问路径取出来
        url_path = environ['PATH_INFO']
        # 判断访问路径,确定响应数据内容,保存到body中
        if url_path == '/index.py':
            body = 'Index Page ...'                 #响应体
        elif url_path == '/center.py':
            body = 'Center Page ...'
        else:
            body = 'Other Page ...'
        # 回调 start_response 函数,将响应状态信息回传给服务器
        start_response('200 OK', [('Content-Type', 'text/html;charset=utf-8')])
        # 返回响应数据内容
        return body
    

    通过代码的优化过和,到这里,基本已经将服务器和框架应用的功能分离。

    3.1.8 总结:

    代码在开发过程中,应该遵循高内聚低耦合的思想
    静态数据是指在访问时不会发生变化的数据
    动态数据是指在访问时会服务的状态,条件等发生不同的变化,得到的数据不同
    通过WSGI接口,实现了服务器和框架的功能分离
    服务器和框架应用的功能分离,使服务器的迁移,维护更加简单

    展开全文
  • Web服务器Boa详细移植流程,通用版(嵌入式Web服务器BOA实现原理.doc)
  • web服务器工作原理及http协议通信

    千次阅读 2011-10-10 10:18:45
    这个客户端通常指的是 Web 浏览器。... Web服务器工作原理简单的可以归纳为:客户机连接服务器,客户端向服务器发送请求,服务器向客户机发送应答,客户机与服务器断开。一个简单的事务处理事
  • web工作原理

    千次阅读 2020-05-29 17:29:55
    1、用户打开客户端,启动浏览器程序,并在浏览器中制定一个URL(统一资源定位器),浏览器便向该URL所指向的Web服务器发出的请求。 2、Web服务器接到浏览器的请求后,把URL转换成页面所在服务器上的文件路径名。 3...
  • web服务器基本原理及Tomcat配置

    千次阅读 2017-03-16 21:32:57
    一、Web服务器基本知识 转自:http://www.cnblogs.com/fnng/archive/2012/11/08/2761713.html  在开始了解Apache前,我们先熟悉一下web服务器,因为apache也是web服务器的一种。  Web系统由客户端(浏览器)和...
  • WEB服务器】什么是WEB服务器

    千次阅读 2022-02-07 16:15:10
    Web服务器一般指的是“网站服务器”,是某种驻留在因特网上的计算机程序,可以向请求终端提供服务,主要功能时存储、处理和传递网页给“客户”,传递内容一般是HTML文档、图像、样式表或脚本等,也可以放置网站文件...
  • WEB工作原理

    千次阅读 2020-05-31 22:26:51
    一、web的工作原理: 1、用户在浏览器中输入要访问的web站点地址或在已打开的站点点击超链接。 2、由dns进行域名解析,找到服务器的IP地址,向该地址指向的web服务器发出请求。 3、web服务器根据请求将URL地址...
  • web系统工作原理

    千次阅读 2022-03-05 09:14:33
    在httpd.conf文件找到Web服务器根目录设置项(38-39行) 将define SRVROOT后的Apache24改为你的Apache24的实际目录。如你将Apache24文件夹复制到了E盘的web目标下了,则将38行改为: Define SRVROOT "E:\web\Apache...
  • Web工作原理.pdf

    2022-05-24 12:47:54
    Web工作原理.pdfWeb工作原理.pdfWeb工作原理.pdfWeb工作原理.pdfWeb工作原理.pdfWeb工作原理.pdfWeb工作原理.pdfWeb工作原理.pdf
  • Web工作原理.docx

    2022-05-12 22:32:45
    Web工作原理.docxWeb工作原理.docxWeb工作原理.docxWeb工作原理.docxWeb工作原理.docxWeb工作原理.docxWeb工作原理.docxWeb工作原理.docx
  • Java Web工作原理

    千次阅读 2018-06-02 15:44:25
    在本章我们将学到如下的内容》HTTP协议原理服务器Web编程原理》Servlet与Web容器》Java Web应用程序的组成》Tomcat介绍 一:1.1解析HTTP协议HTTP:超文本传输协议(HyperText Transfer Protocol)HTTP是一种无...
  • 转载来源 :http://www.shazidoubing.com/fwq/webserv/385.html... 对于普通的上网过程,系统其实是这样做的:浏览器本身是一个客户端,当你输入URL的时候,首先浏览器会去请求DNS服务器,通过DNS获取相应的 域名对...
  • Web服务器工作原理及其相关协议

    万次阅读 2016-04-21 16:52:30
    通俗的说,Web服务器是可以向发出请求的浏览器提供文档的程序。 1、服务器是一种被动程序:只有当Internet上运行在其他计算机中的浏览器发出请求时,服务器才会响应。 2 、最常用的Web服务器是Apache和...
  • 什么是Web?及web服务器原理

    千次阅读 2016-12-10 23:53:06
    什么是WebWeb就是一种超文本信息系统,Web的一个主要的概念就是超文本连接,它使得文本不再象一本书一样是固定的线性的。而是可以从一个位置跳到另外的位置。你可以从中获取更多的信息。可以转到别的主题上。...
  • Web服务器工作原理(一)

    千次阅读 2016-11-21 15:16:31
    Web服务器工作原理(一)12@(服务器)[Web服务器, Notes] VICTORY LOVES PREPARATIONWeb服务器的工作原理一12 思维导图 一web服务器应用服务器和web容器 web服务器 应用服务器 web容器 二Servlet 三ServletContext...
  • web工作原理

    千次阅读 2017-03-02 16:41:43
    Web服务器工作原理概述 很多时候我们都想知道,web容器或web服务器(比如Tomcat或者jboss)是怎样工作的?它们是怎样处理来自全世界的http请求的?它们在幕后做了什么动作?Java Servlet API(例如ServletContext...
  • web工作原理

    千次阅读 2018-04-08 23:40:17
    作为一名想学习网站开发, 或者更专业一点说叫"... 但是, 在你开始之前, 请稍安勿躁, 了解一下网站是如何工作的往往是一件"磨刀不误砍柴工"的事情. 曾经接触过一些公司里刚入职的程序...
  • Web服务器工作原理

    千次阅读 2015-12-01 11:23:40
    了解WEB服务器工作原理和相关概念是后台开发人员的必修课,这篇文章来自 : Web服务器工作原理很多时候我们都想知道,web容器或web服务器(比如Tomcat或者jboss)是怎样工作的?它们是怎样处理来自全世界的http...
  • 服务器工作原理

    万次阅读 2016-05-31 23:21:42
    (2)单机程序工作原理 单机,即不连接到其他计算机的计算机,不在网络中。例如:两单机A、B,只...(3)客户机/服务器程序工作原理 将单机连成网络,如将A与B连成网络,则可以使它们之间提供服务,如A向B提供服
  • 我们基本每天都在通过WEB浏览器,去浏览一些新闻,看看视频之类的。...那顺道就来简单的看一下,所谓的Web服务器(例如知名的Tomcat)与浏览器,基本的实现原理是什么样的呢? 首先可以明确的就是,例如我们所...
  • WEB服务器端技术

    千次阅读 2022-04-11 17:39:07
    WEB服务器端技术 客户端是与用户交互的唯一接口,对于软件测试人员来说不可掉以轻心,那么服务器端又需要我们了解哪些技术呢? 事实上,对于Web系统来说,相比于客户端技术,服务器端技术更是深不可测,其各类技术...
  • 首先,我们需要购买阿里云服务器和域名。 域名建议用.com后缀的(一般五十左右),想要便宜的域名可以买.top等后缀的(一般几块钱)。 点击这里购买域名 云服务器的话,根据自己的需要购买,如果只是简单的发发文章...
  • Web缓存工作原理

    千次阅读 2017-12-21 16:15:40
    但除了一些微妙的细节之外,Web缓存的基本工作原理大多很简单。对一条HTTP GET报文的基本缓存处理过程包括7个步骤: 接收——缓存从网络中读取抵达的请求报文解析——缓存对报文进行解析,提取URL和各种首部查询...
  • web服务器、应用服务器和常见的服务器概念

    千次阅读 多人点赞 2020-04-17 16:36:01
    什么是web服务器,什么是应用服务器? 浏览器的编译原理是什么? http的头文件为何要这样配置? Nginx,Apache等为何要这样操作? 不同的服务器软件有什么作用? 而网上关于http的实战讲解一般都是以操作为主,涉及...
  • WEB服务器有哪几种

    千次阅读 2020-11-03 10:22:00
    如今的Web服务器有很多种,大家在做项目的时候根据自己的需求进行灵活的选择。下面小编就给大家分享一下目前都有哪些Web服务器。  1.Apache  Apache也被叫做httpd服务器,是目前使用最广泛的web服务器,它被应用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 401,890
精华内容 160,756
关键字:

web服务器工作原理