这是我参与「第五届青训营 」伴学笔记创作活动的第 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的使用且易于理解。