zoukankan      html  css  js  c++  java
  • GO.Web服务

    Web基础

    Web服务器的一般工作原理可以简单地归纳为:

    客户机浏览器通过TCP/IP协议建立到服务器的TCP连接

    客户端向服务器发送HTTP协议请求包,请求服务器里的资源文档

    服务器向客户机发送HTTP协议应答包,如果请求的资源包含有动态语言的内容,那么服务器会调用动态语言的解释引擎负责处理“动态内容”,并将处理得到的数据返回给客户端

    客户机与服务器断开。由客户端解释HTML文档,在客户端屏幕上渲染图形结果

    URL(Uniform Resource Locator)统一资源定位符,描述一个网络上的资源,schema://host[:port#]/path/.../[?query-string][#anchor]

    scheme 指定低层使用的协议(例如:http, https, ftp)

    host HTTP服务器的IP地址或者域名

    port# HTTP服务器的默认端口是80,这种情况下端口号可以省略。如果使用了别的端口,必须指明,例如 http://www.path 访问资源的路径

    query-string 发送给http服务器的数据

    anchor 锚

    HTTP请求包(浏览器信息)
    Request包的结构,:分为3部分,第一部分叫Request line(请求行), 第二部分叫Requestheader(请求头),第三部分是body(主体)。header和body之间有个空行,如下:

    GET /domains/example/ HTTP/1.1 //请求行: 请求方法 请求URI HTTP协议/协议版本

    Host:www.iana.org //服务端的主机名

    User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,

    /*;q=0.8 //客户端能接收的mine

    Accept-Encoding:gzip,deflate,sdch //是否支持流压缩

    Accept-Charset:UTF-8,*;q=0.5 //客户端字符编码集

    //空行,用于分割请求头和消息体

    //消息体,请求资源参数,例如POST传递的参数

    HTTP协议定义的与服务器交互的请求方法,最基本的有4种,分别是GET,POST,PUT,DELETE. 一个URL地址用于描述一个网络上的资源,而HTTP中的GET, POST, PUT,

    DELETE就对应着对这个资源的查,改,增,删4个操作。

    最常见的就是GET和POST了。GET一般用于获取/查询资源信息,而POST一般用于更新资源信息. GET和POST的区别

    1. GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连. POST方法是把提交的数据放在HTTP包的Body中.

    2. GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制.

    3. GET方式提交数据,会带来安全问题,通过GET方式提交数据时,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得信息。

    HTTP响应包(服务器信息)

    HTTP的response包,结构如下:

    HTTP/1.1 200 OK //状态行

    Server: nginx/1.0.8 //服务器使用的WEB软件名及版本

    Date:Date: Tue, 30 Oct 2012 04:14:25 GMT //发送时间

    Content-Type: text/html //服务器发送信息的类型

    Transfer-Encoding: chunked //表示发送HTTP包是分段发的

    Connection: keep-alive //保持连接状态

    Content-Length: 90 //主体内容长度

    //空行 用来分割消息头和主体

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... //消息体

    Response包中的第一行叫做状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成。

    状态码用来告诉HTTP客户端,HTTP服务器是否产生了预期的Response。HTTP/1.1协议中定义了5类状态码, 如下:

    1XX 提示信息 - 表示请求已被成功接收,继续处理

    2XX 成功 - 表示请求已被成功接收,理解,接受

    3XX 重定向 - 要完成请求必须进行更进一步的处理

    4XX 客户端错误 - 请求有语法错误或请求无法实现

    5XX 服务器端错误 - 服务器未能实现合法的请求

    浏览器第一次请求url,服务器端返回的是html页面,然后浏览器开始渲染HTML:当解析到HTML DOM里面的图片连接,css脚本和js脚本的链接,浏览器就会自动发起一个

    请求静态资源的HTTP请求,获取相对应的静态资源,然后浏览器就会渲染出来,最终将所有资源整合、渲染,完整展现在我们面前的屏幕上。

    网页优化方面有一项措施是减少HTTP请求次数,就是把尽量多的css和js资源合并在一起,目的是减少网页请求静态资源的次数,提高网页加载速度,同时减缓服务器的压力。

    GO搭建web服务器

    Web是基于http协议的一个服务,Go语言里面提供了一个完善的net/http包,通过http包可以很方便的就搭建起来一个可以运行的web服务。同时使用这个包能很简单地对web

    的路由,静态文件,模版,cookie等数据进行设置和操作。

    http包建立web服务器

    package main
    
    import (
    	"fmt"
    	"log"
    	"net/http"
    	"strings"
    )
    
    func sayhelloName(w http.ResponseWriter, r *http.Request) {
    	r.ParseForm()       //解析参数,默认是不会解析的
    	fmt.Println(r.Form) //这些信息是输出到服务器端的打印信息
    	fmt.Println("path", r.URL.Path)
    	fmt.Println("scheme", r.URL.Scheme)
    	fmt.Println(r.Form["url_long"])
    	for k, v := range r.Form {
    		fmt.Println("key:", k)
    		fmt.Println("val:", strings.Join(v, ""))
    	}
    	fmt.Fprintf(w, "Hello astaxie!") //这个写入到w的是输出到客户端的
    }
    
    func main() {
    	http.HandleFunc("/", sayhelloName)       //设置访问的路由
    	err := http.ListenAndServe(":9090", nil) //设置监听的端口
    	if err != nil {
    		log.Fatal("ListenAndServe: ", err)
    	}
    }
    

    web工作方式的几个概念

    Request:用户请求的信息,用来解析用户的请求信息,包括post、get、cookie、url等信息

    Response:服务器需要反馈给客户端的信息

    Conn:用户的每次请求链接

    Handler:处理请求和生成返回信息的处理逻辑

    http包运行机制

    1.创建Listen Socket, 监听指定的端口, 等待客户端请求到来。

    2. Listen Socket接受客户端的请求, 得到Client Socket, 接下来通过Client Socket与客户端通信。

    3. 处理客户端的请求, 首先从Client Socket读取HTTP请求的协议头, 如果是POST方法, 还可能要读取客户端提交的数据, 然后交给相应的handler处理请求, handler处理完毕准备

    好客户端需要的数据, 通过Client Socket写给客户端。

    Go的http包详解

    TODO:

    构建web服务Go代码的执行流程

    首先调用Http.HandleFunc,按顺序做了几件事:

    1 调用了DefaultServerMux的HandleFunc

    2 调用了DefaultServerMux的Handle

    3 往DefaultServeMux的map[string]muxEntry中增加对应的handler和路由规则

    其次调用http.ListenAndServe(":9090", nil),按顺序做了几件事情:

    1 实例化Server

    2 调用Server的ListenAndServe()

    3 调用net.Listen("tcp", addr)监听端口

    4 启动一个for循环,在循环体中Accept请求

    5 对每个请求实例化一个Conn,并且开启一个goroutine为这个请求进行服务go c.serve()

    6 读取每个请求的内容w, err := c.readRequest()

    7 判断handler是否为空,如果没有设置handler(这个例子就没有设置handler),handler就设置为DefaultServeMux

    8 调用handler的ServeHttp

    9 在这个例子中,下面就进入到DefaultServerMux.ServeHttp

    10 根据request选择handler,并且进入到这个handler的ServeHTTP mux.handler(r).ServeHTTP(w, r)

    11 选择handler:

    A 判断是否有路由能满足这个request(循环遍历ServerMux的muxEntry)

    B 如果有路由满足,调用这个路由handler的ServeHttp

    C 如果没有路由满足,调用NotFoundHandler的ServeHttp

    #笔记内容来自 《Go Web编程》

  • 相关阅读:
    CSV 文件的读写(函数)
    携带cookies请求github个人信息(类封装)
    网络和http协议理论
    思卡乐科技发布SR3系列RFID产品
    爱立信开始大规模mesh网络测试
    NB-IoT物联网,来了
    想象力是我们的局限,蓝牙5应用初探
    RFID电动车管理,智慧城市物联网建设的入口
    蓝牙模块选择经验谈
    RFID电动自行车与共享单车之物联网比较
  • 原文地址:https://www.cnblogs.com/shanhm1991/p/7144475.html
Copyright © 2011-2022 走看看