本文共 5596 字,大约阅读时间需要 18 分钟。
CS即客户端、服务器编程。客户端、服务端之间需要使用Socket,约定协议、版本(往往使用的协议是TCP或者UDP),指定地址和端口,就 可以通信了。 客户端、服务端传输数据,数据可以有一定的格式,双方必须先约定好。
BS编程,即Browser、Server开发。Browser浏览器,一种特殊的客户端,支持HTTP(s)协议,能够通过URL向服务端发起请求,等待服务端返回HTML 等数据,并在浏览器内可视化展示的程序。 Server,支持HTTP(s)协议,能够接受众多客户端发起的HTTP协议请求,经过处理,将HTML等数据返回给浏览 器。
本质上来说,BS是一种特殊的CS,即客户端必须是一种支持HTTP协议且能解析并渲染HTML的软件,服务端必须是能够接收多客户端HTTP访问的服务器软件。 HTTP协议底层基于TCP协议实现。
BS开发分为两端开发:
无状态:指的是服务器无法知道2次请求之间的联系,即使是前后2次同一个浏览器也没有任何数据能够判断出是同 一个浏览器的请求。后来可以通过cookie、session来判断。有连接:是因为它基于TCP协议,是面向连接的,需要3次握手、4次断开。 短连接:Http 1.1之前,都是一个请求一个连接,而Tcp的连接创建销毁成本高,对服务器有很大的影响。所以, 自Http 1.1开始,支持keep-alive,默认也开启,一个连接打开后,会保持一段时间(可设置),浏览器再访问该 服务器就使用这个Tcp连接,减轻了服务器压力,提高了效率。
Http协议是无状态协议。同一个客户端的两次请求之间没有任何关系,从服务器端角度来说,它不知道这两个请求来自同一个客户端。
URL可以说就是地址,uniform resource locator 统一资源定位符,每一个链接指向一个资源供客户端访问。schema://host[:port#]/path/.../[;url-params][?query-string][#anchor]
scheme 模式、协议:http、ftp、https、fifile、mailto等等。host:port :www.baidu.com:80 ,80端口是默认端口可以不写。域名会使用DNS解析,域名会解析成IP才能使用。实际上会对解析后返回的IP的TCP的80端口发起访问。/path/to/resource:path,指向资源的路径。?key1=value1&key2=value2: query string,查询字符串,问号用来和路径分开,后面key=value形式,且使用&符号分割。
消息分为Request、Response。Request:浏览器向服务器发起的请求 Response:服务器对客户端请求的响应。
请求报文:
常见的传递信息的方式:
响应报文:
曾经Cookie唯一在浏览器端存储数据的手段,目前浏览器端存储数据的方案很多,Cookie正在被淘汰。当服务器收到HTTP请求时,服务器可以在响应头里面添加一个Set-Cookie键值对。浏览器收到响应后通常会保存这些Cookie,之后对该服务器每一次请求中都通过Cookie请求头部将Cookie信息发送给服务器。另外,Cookie的过期时间、域、路径、有效期、适用站点都可以根据需要来指定。可以使用 Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE
cookie的缺点:
WEB 服务器端,尤其是动态网页服务端Server,有时需要知道浏览器方是谁?但是HTTP是无状态的,怎么办?
服务端会为每一次浏览器端第一次访问生成一个SessionID,用来唯一标识该浏览器,通过Set-Cookie发送到浏览器端。浏览器端收到之后并不永久保持这个Cookie,只是会话级的。浏览器访问服务端时,会使用Cookie,也会带上这 个SessionID的Cookie值。
服务端会维持这个SessionID一段时间,如果超时,会清理这些超时没有人访问的SessionID。如果浏览器端发来的 SessionID无法在服务端找到,就会自动再次分配新的SessionID,并通过Set-Cookie发送到浏览器端以覆盖原有的 存在浏览器中的会话级的SessionID。
wsgi(Web Server Gateway Interface) 主要规定了服务器端和应用程序间的接口。
wsgiref是Python提供的一个WSGI参考实现库,不适合生产环境使用。wsgiref.simple_server 模块实现一个简单的WSGI HTTP服务器。
import wsgireffrom wsgiref.simple_server import make_server, demo_app, WSGIServer, WSGIRequestHandler# 启动一个WSGI服务器wsgiref.simple_server.make_server(host, port, app, server_class=WSGIServer,handler_class=WSGIRequestHandler)# 一个两参数函数,小巧完整的WSGI的应用程序的实现wsgiref.simple_server.demo_app(environ, start_response)# 返回文本例子ip = '127.0.0.1'port = 9999server = make_server(ip, port, demo_app) # demo_app应用程序,可调用server.serve_forever() # server.handle_request() 执行一次
WSGI 服务器作用:
from wsgiref.simple_server import make_server # , demo_app # 不能用于生产环境# simple_server只是作为参考用,不能用于生产环境return_res = b'abc~~~'def app(environ, start_response): # 函数实现 for k, v in environ.items(): if k.startswith('HTTP_'): print(k, v) start_response("200 OK", [('Content-Type', 'text/plain; charset=utf-8')]) return [return_res]class App: # 通过类实现 def __init__(self, environ, start_response): self.environ = environ self.start_response = start_response def __iter__(self): self.start_response("200 OK", [('Content-Type', 'text/plain; charset=utf-8')]) yield from [b'Curry ', b'Green']class Application: # 通过类实现 def __call__(self, environ, start_response): for k, v in environ.items(): if k.startswith('HTTP_'): print(k, v) start_response("200 OK", [('Content-Type', 'text/html; charset=utf-8')]) # 返回可迭代对象 html = "金州拉文
".encode("utf-8") return [html]# 上述三种方法选一种即可# ws = make_server('127.0.0.1', 9999, app) # app为应用程序,可调用# ws = make_server('127.0.0.1', 9999, App) # app为应用程序,可调用ws = make_server('127.0.0.1', 9999, Application()) # app为应用程序,可调用ws.serve_forever() # server.handle_request()执行一次# app 先调用start_response;demo_app返回可迭代对象,内部是内容,最后拼接
environ是包含Http请求信息的dict字典对象
start_response应该在返回可迭代对象之前调用,因为它返回的是Response Header。返回的可迭代对象是 Response Body。
服务器程序需要调用符合上述定义的可调用对象APP,传入environ、start_response,APP处理后,返回响应头和可迭代对象的正文,由服务器封装返回浏览器端。
# 返回网页的例子from wsgiref.simple_server import make_serverdef application(environ, start_response): status = '200 OK' headers = [('Content-Type', 'text/html;charset=utf-8')] start_response(status, headers) # 返回可迭代对象 html = '马哥教育欢迎你
'.encode("utf-8") return [html]ip = '127.0.0.1'port = 9999server = make_server(ip, port, application)server.serve_forever() # server.handle_request() 一次
simple_server 只是参考用,不能用于生产环境。
WSGI WEB服务器:
WSGI APP应用程序:
转载地址:http://mvfvi.baihongyu.com/