74-golangHTTP编程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33781658/article/details/84591695


我们浏览网页的时候
会打开浏览器,输入网站
然后按下回车键

然后就会显示出我们想要的内容
那么过程到底是怎么样的呢

1.浏览器本身是一个客户端,输入URL的时候,会请求DNS服务器
2.通过DNS服务器获取这个域名对应的IP
3.通过这个IP地址找到对应的服务器
4.建立TCP连接
5.浏览器发送HTTP请求包
6.服务器接收到请求包
7.服务器调用自身服务,返回HTTP响应包
8.客户端收到响应包
9.客户端渲染response包里的主体
10.收到全部内容之后就断开与服务器的连接




DNS域名服务器
domain name server
是进行域名和与之对应IP转换的服务器
DNS中保存了一张域名解析表,来解析消息的域名

WEB服务器
也成为HTTP服务器,通过HTTP(超文本传输协议)与客户端通信

WEB服务器工作原理
1.客户端通过TCP/IP协议建立与服务器的连接
2.客户端向服务器发送HTTP协议请求包,请求服务器里的资源
3.服务器向客户端发送HTTP响应包,如果请求的资源包含动态语言的内容
服务器会调用动态语言的解释引擎来处理动态内容,将处理结果返回给客户端
4.客户端与服务器断开,由客户端解释HTML文档,在客户端渲染结果


HTTP协议
hypertext transfer protocol
超文本传输协议
是互联网应用最为广泛的一种网络协议,详细规定了浏览器和万维网服务器之间
通信的规则,通过因特网传送万维网文档数据传送协议
HTTP协议通常承载于TCP协议智商,有时候也承载于TLS或SSL协议层之上,
也就是我们说的HTTPS


地址URL
URL全称是uniform resource locator
统一资源标识符
也可以理解为网络文件的路径,表示网络资源
基本的URL结构包含了
1.协议
2.IP地址
3.路径
4.文件名
比如
http://localhost:8080/abc.txt



我们可以写一段代码看一下请求包是什么样子的
也就是看看我们的conn里面都是什么

func main() {
	//创建监听者
	listener, err := net.Listen("tcp", "127.0.0.1:8000")
	if err != nil {
		fmt.Println("Listen err:", err)
		return
	}
	defer listener.Close()

	//阻塞等待客户端连接
	conn, err := listener.Accept()
	if err != nil {
		fmt.Println("Accept err:", err)
		return
	}
	defer conn.Close()

	fmt.Println(conn.RemoteAddr().String(), "连接成功")
	//切片缓冲区,接收客户端发送数据
	buf := make([]byte, 4096)
	//n 接收数据的长度
	n, err := conn.Read(buf)
	if err != nil {
		fmt.Println("Read err:", err)
		return
	}
	//切片截取
	result := string(buf[:n])

	fmt.Printf("#######\n%s\n#######", result)
}




1. 请求行
     请求行由方法字段、URL 字段 和HTTP 协议版本字段 3个部分组成,他们之间使用空格隔开。常用的 HTTP 请求方法有 GET、POST。
     GET:

     - 当客户端要从服务器中读取某个资源时,使用GET 方法。GET 方法要求服务器将URL 定位的资源放在响应报文的数据部分,回送给客户端,即向服务器请求某个资源。
     - 使用GET方法时,请求参数和对应的值附加在 URL 后面,利用一个问号(“?”)代表URL 的结尾与请求参数的开始,传递参数长度受限制,因此GET方法不适合用于上传数据。
     - 通过GET方法来获取网页时,参数会显示在浏览器地址栏上,因此保密性很差。

     POST:

     - 当客户端给服务器提供信息较多时可以使用POST 方法,POST 方法向服务器提交数据,比如完成表单数据的提交,将数据提交给服务器处理。
     - GET 一般用于获取/查询资源信息,POST 会附带用户数据,一般用于更新资源信息。POST 方法将请求参数封装在HTTP 请求数据中,而且长度没有限制,因为POST携带的数据,在HTTP的请求正文中,以名称/值的形式出现,可以传输大量数据。

  2. 请求头部
     请求头部为请求报文添加了一些附加信息,由“名/值”对组成,每行一对,名和值之间使用冒号分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:
     请求头	含义

     - User-Agent	请求的浏览器类型
     - Accept	客户端可识别的响应内容类型列表,星号“ * ”用于按范围将类型分组,用“ */* ”指示可接受全部类型,用“ type/* ”指示可接受 type 类型的所有子类型
     - Accept-Language	客户端可接受的自然语言
     - Accept-Encoding	客户端可接受的编码压缩格式
     - Accept-Charset	可接受的应答的字符集
     - Host	请求的主机名,允许多个域名同处一个IP 地址,即虚拟主机
     - Connection	连接方式(close或keepalive)
     - Cookie	存储于客户端扩展字段,向同一域名的服务端发送属于该域的cookie

  3. 空行
     最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。

  4. 请求包体
     请求包体不在GET方法中使用,而在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求包体相关的最常使用的请求头部是包体类型Content-Type和包体长度Content-Length。



响应报文格式

要想获取响应报文,必须先发送请求报文给web服务器。服务器收到并解析浏览器(客户端)发送的请求报文后,借助http协议,回复相对应的响应报文。
?	下面我们借助net/http包,创建一个最简单的服务器,给浏览器回发送响应包。首先注册处理函数http.HandleFunc(),设置回调函数handler。而后绑定服务器的监听地址http.ListenAndserve()。
这个服务器启动后,当有浏览器发送请求,回调函数被调用,会向浏览器回复“hello world”作为网页内容。当然,是按照http协议的格式进行回复。




func main() {

	//注册监听
	http.HandleFunc("/test/", handlerFunc)
	
	//创建监听
	http.ListenAndServe("127.0.0.1:8080", nil)

}

func handlerFunc(writer http.ResponseWriter, request *http.Request) {
	//获取url
	url := request.URL.String()

	//拼接路径path
	path := path.Join("f:/", url)

	//读取文件
	bytes, err := ioutil.ReadFile(path)
	if err != nil {
		writer.Write([]byte("404"))
		return
	}

	//写入文件数据
	writer.Write(bytes)
}


猜你喜欢

转载自blog.csdn.net/qq_33781658/article/details/84591695
74
今日推荐