这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记;
JSON处理
json的场景应用
json数据格式
在json中一切皆为对象,一切数据(字符串,数字,字母,自定义对象等)都可以同json来表示;JSON用键值对的方式保存数据;
json解析
package main
import(
"fmt"
"encoding/json"
//首先导入json工具的包
)
type user struct{
Name string
Age int
Hobby []string
}
func main(){
var a user
a.Name="张三"
a.Age=19
a.Hobby=[]string{"golang","java","game"}
buf,err:=json.Marshal(a)//进行序列化
if err==nil {
fmt.Println(string(buf))//转化为字符串的json数据
}
fmt.Println(a)
buf,err=json.MarshalIndent(a,"","\t")
//类似Marshal但会使用缩进将输出格式化
if err==nil {
fmt.Println(string(buf))
}
}
输出结果:
{"Name":"张三","Age":19,"Hobby":["golang","java","game"]}
{张三 19 [golang java game]}
{
"Name": "张三",
"Age": 19,
"Hobby": [
"golang",
"java",
"game"
]
}
go发送http请求并解析json
首先发送http请求需要导入的包有io/ioutil,log,net/http,strings;
步骤:
- 首先创建一个http连接:
client := &http.Client{} - 创建一个只读的读取数据的Reader,并在里面赋予一些参数:
var data = strings.NewReader(`{"trans_type":"en2zh","source":"good"}`)
- 创建一个request请求:
req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
第一个参数是请求方式(get/post等),第二个参数是请求地址,第三个参数昂就是上面创建的Reader
-
之后根据要求在自己设置这个request请求的请求头的各项信息
-
http连接发送这个request请求:
resp, err := client.Do(req)响应是resp,如果报错的话err!=nil; -
通过resp的响应码
resp.StatusCode判断请求是否成功,成功的话响应码就是200; -
如果请求成功的话我们就就可以写一个结构体将返回的json串反序列化到结构体里面,这样就是易读的信息了;
-
最后为了响应数据泄露我们需要关闭这个流
defer resp.Body.Close()
socks5代理服务器
socks5代理服务器由于它的协议都是明文传输的,所以它不能用来翻墙,socks5就相当于在防火墙开了个小口子,用户可以根据单个端口去访问内部的所有资源,使访问某些资源不再那么麻烦;
socks5代理服务器原理
大致过程是浏览器先和socks5代理建立TCP连接,然后socks5代理再和真正的服务器建立TCP连接。这里可以分成四个阶段,握手阶段、认证阶段、请求阶段、relay阶段:
- 握手阶段,浏览器会向socks5代理发送请求,包的内容包括—个协议的版本号,还有支持的认证的种类,socks5服务器会选中—个认证方式,返回给浏览器。如果返回的是
00的话就代表不需要认证,返回基他类型的话会开始认证流程。
- 认证阶段略
-
请求阶段,认证通过之后浏览器会socks5代理服务器发起请求。主要信息包括
版本号和请求类型,一般主要是connection请求,代表socks5代理服务器要和某个域名或者某个IP地址某个端口建立TCP连接。代理服务器收到响应之后,会真正和后端服务器建立连接,然后返回一个响应。 -
relav阶段。此时浏览器会正常发送请求,然后代理服务器接收到请求之后,会直接把请求转换到真正的服务器上。如果真正的服务器返回响应的话,那么也会把请求转发到浏览器这边。实际上代理服务器并不关心流量的细节,可以是HTTP流量,也可以是其它TCP流量。
写一个简单的TCP echo server实现
package main
import(
"bufio"
"log"
"net"
)
//bufio包实现了有缓冲的I/O。
//它包装一个io.Reader或io.Writer接口对象,
//创建另一个也实现了该接口,且同时还提供了缓冲
//和一些文本I/O的帮助函数的对象。
func process(conn net.Conn){
defer conn.Close()//关闭连接
reader:=bufio.NewReader(conn)
//NewReader创建一个具有默认大小缓冲,从conn读取的*Reader。
for{
b,err:=reader.ReadByte()
//ReadByte读取并返回一个字节。如果没有可用的数据,会返回错误
if err!=nil{
break
}
_,err=conn.Write([]byte{b})
//Write将p的内容写入缓冲。返回写入的字节数。
//如果返回字节数<len(b),还会返回一个错误说明原因。
if err!=nil{
break
}
}
}
func main(){
server,err:=net.Listen("tcp","127.0.0.1:1080")
//创建一个tcp连接
if(err!=nil){//判断连接是否出错
log.Println("连接出错!!")
panic(err)
}
for{
client,err:=server.Accept();
//持续接收请求,每次一个
if(err!=nil){//判断是否接收成功
log.Println("接收出错!!")
panic(err)
}
go process(client)
//开启一个子线程执行(可承受上万次并发)
}
}