web服务器的工作原理
- 客户端通过TCP/IP协议建立到服务器的TCP的连接
- 客户端向服务器发送HTTP协议请求包,请求服务器里的资源文档
- 服务器向客户端发送HTTP协议应答包,如果请求的资源包含动态语言的内容,那么服务器会调用动态语言解释引擎负责处理动态内容,并将处理得到的数据返回给客户端
- 客户端与服务器断开。由客户端解释HTML文档,渲染图形结果
URL和DNS解析
URL(Uniform Resource Locator)
统一资源定位符的英文缩写,基本格式如下:
- scheme://host[:port#]/path/.../[?query-string][#anchor]
- scheme 指定底层使用协议(http,https,ftp)
- host HTTP服务器的IP地址或者域名
- port# HTTP服务器默认端口是80,可以省略。如果使用了别的端口必须指定
- path 访问资源的路径
- query-string 发送给http服务器的数据
- anchor 锚
DNS(Domain Name System)
域名系统英文缩写,使用TCP/IP网络,从事将主机名或者域名转换为实际IP地址的工作
DNS解析过程
- 浏览器中输入域名,操作系统会先检查自己本地的hosts文件是否有这个网络映射关系,如果有,就先调用这个IP地址映射,完成域名解析
- hosts没有域名,查找本地DNS解析器缓存,如果有直接返回
- 还没找到,会查找TCP/IP参数中设置的首选DNS服务器,我们叫它本地DNS服务器,此服务收到查询时,如果要查询的域名包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性
- 如果要查询的域名,不由本地DNS服务器区域解析,但该服务已经缓存了地址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性
- 上述过程实习,则根据本地DNS服务器的设置进行查询,如果未用转发模式,则把请求发给根服务器,根服务器返回一个负责该顶级服务器的IP,本地DNS服务器收到IP信息后,再连接该IP上的服务器进行解析,如果仍然无法解析,则发送下一级DNS服务器,重复操作,直到找到
- 转发模式则把请求转发至上一级DNS服务器,如果仍然不能解析,再转发给上上级。不管是否转发,最后都把结果返回给本地DNS服务器
- 上述一个是迭代查询,一个是递归查询。递归查询的过程是查询者发生了更替,而迭代查询过程,查询者不变
HTTP协议详解
HTTP是一种让web服务器与浏览器(客户端)通过internet发送与接受数据的协议
建立在TCP协议之上,一般采用80端口
它是一个请求、响应协议。客户端建立连接并发送请求。服务端不能主动去与客户端联系,也不能发送一个回调连接,客户端可提前中断连接。
HTTP请求是无状态的,每个请求之间没有关联。为了解决这个问题引入了cookie机制
Dos(拒绝服务攻击)和Ddos(分布式拒绝服务攻击),是一种利用TCP协议缺陷,发送大量伪造TCP连接请求,从而使被攻击方资源耗尽
HTTP请求包
- Request line
- Request header
- body
请求方法
GET、PSOT、PUT、DELETE
GET和POST区别
- GET提交的数据放在URL之后,以?分割URL和传输数据,参数之间以&相连。POST方法把提交数据放在HTTP的body中
- GET提交数据大小有限制,因为浏览器对URL长度有限制,而POST方法提交数据没有限制
- GET提交数据有安全问题,用户名和密码都出现在URL上,如果页面被缓存其他人可以访问这台机器就可以获得帐号和密码
HTTP响应包
状态行
服务器使用的WEB软件名及版本、发送时间、服务器发送信息的类型、表示http包的分段发送、保持连接状态、主题内容长度、空行用来分割消息头和主题、消息体
状态行由HTTP协议版本号、状态吗、状态消息三部分组成
状态吗
- 1XX 提示信息--表示请求被成功接收,继续处理
- 2XX 成功--表示请求被成功接收,理解,接受
- 3XX 重定向--要完成请求必须进行更进一步处理
- 4XX 客户端错误--请求语法错误或者请求无法实现
- 5XX 服务器端错误--服务器未能实现合法请求
HTTP协议和Connection:keep_alive的区别
HTTP是一个无状态面向连接的协议,无状不代表HTTP不能保持TCP连接
keep-alive,当一个网页打开完成后,客户端和服务端之间用于HTTP数据的TCP连接不会关闭,,再次访问时,继续使用之前建立的连接
keep-alive不会永久保持连接,有一个保持时间
第一次请求url,服务器返回的是html页面,然后浏览器开始渲染HTML:当解析到HTML DOM里面的图片连接,css脚本和js脚本的连接,浏览器会自动发起一个请求静态资源的HTTP请求,获取相应静态资源,厚燃浏览器会渲染出来,最终将所有资源整合、渲染、完整展现在屏幕上。
网页优化有一向措施是减少HTTP请求次数,把尽量多的css和js资源合并在一起
http包运行机制
创建listen socket,监听指定端口,等待客户端请求到来
listen socket接受客户端的请求,得到client socket,接下来通过client socket与客户端通信
处理客户端请求,先从client socket读取http请求的协议头,如果是POST方法,还可能要读取客户端提交的数据,然后交给相应的handler处理请求,handler处理完毕后,通过client socket写给客户端
梳理代码执行过程
- 首先调用Http.HandleFunc,按顺序做如下操作
- 调用DefaultServerMux的HandleFunc
- 调用DefaultServerMux的Handle
- 往DefaultServeMux的map[string]muxEntry中增加对应的handler和路由规则
- 其次调用http.ListenAndServe,按顺序做如下操作
- 实例化Server
- 调用Server的ListenAndServe()
- 调用net.listen("tcp",addr)监听端口
- 启动一个for循环,在循环体中Accept请求
- 对每个请求实例化一个Conn,并且开启一个goroutine为这个请求进行服务go c.serve()
- 读取每个请求的内容w, err := c.readRequest()
- 判断handler是否为空,如果没有设置handler,handler就设置为DefaultServeMux
- 调用handler的ServeHttp
- 根据request选择handler,并且进入到这个handler的ServeHttp
- 选择handler
- 判断是否有路由能满足这个request
- 如果有路由满足,调用路由handler的ServeHttp
- 如果没有路由满足,调用NotFoundHandler的ServeHttp
表单
Request本身提供了FormValue()函数,如r.Form["username"]可以写成r.FormValue("username")
r.FormValue会自动调用r.ParseForm
模版使用
变量名首字母要大写,不然模版无法识别
|
请发表评论