后端Go基础 | 青训营笔记

79 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

一、本堂课重点内容:

go 的基本语法
三个简单的go项目

二、课程实践

2.1猜数字大小

使用随机数需要先设置种子

rand.Seed(time.Now().UnixNano())
secretNumber := rand.Intn(maxNum)

bufio.NewReader(os.Stdin)获取用户的输入流,比较大小并置于循环中

strconv.Atoi可以快速将十进制字符串转化为数字

2.2线上字典

功能实现的主要思想为: 首先构造结构体来对应要发送的json信息,将结构体序列化得到字节数组,再将其转化为字节流然后调用接口。
接收响应消息,响应体resp.Body是io.ReadCloser类型,也是一种流,将其转化为字节数组,再进行反序列化即可得到结果。

代码生成: 在开发者工具页面复制curl到curlconverter.com/go/可以生成代码,自动设置好请求头等内容,方便编码。 oktools.net/json2go 是josn转go结构体的,可以将网页的返回信息复制得到对应接口的结构体。
响应体resp.Body使用io.ReadAll方法转化为字节数组[]byte.再使用Unmarshal反序列化。

2.3代理服务器

原理:通过代理服务器与网页建立tcp请求,代理服务器获得响应后将内容返回给客户端。 net.Listen监听一个端口server.Accept()接收一个请求得到一个连接client

func process(conn net.Conn) {
	defer conn.Close()
	reader := bufio.NewReader(conn)
	err := auth(reader, conn)
	if err != nil {
		log.Printf("client %v auth failed:%v", conn.RemoteAddr(), err)
		return
	}
	err = connect(reader, conn)
	if err != nil {
		log.Printf("client %v auth failed:%v", conn.RemoteAddr(), err)
		return
	}
}

其中调用auth和connect
auth读取客户端发来的报文,返回conn.Write([]byte{socks5Ver, 0x00})

connect中, buf := make([]byte, 4)创建长度为4的缓冲区,验证每个字段的合法性,对不同的atyp采取不同的处理
最后,在relay阶段dest, err := net.Dial("tcp", fmt.Sprintf("%v:%v", addr, port))向对应的域名加端口建立tcp连接。建立浏览器和服务器的双向数据转发,启动两个goroutine,出错时调用cancle()来停止连接,由于goroutine同时开启,为避免直接返回,使用**<-ctx.Done() 等待context执行完成 任何一个方向的拷贝失败会结束ctx。

三、课后个人总结:

基本语法较好理解,最后代理服务器的项目可能涉及后面课程的内容,需要以后再回头看来加深理解,前两个项目熟悉了go的使用且易于理解。