这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
前言
上一篇已经是10天前了,我太摸鱼了,赶工赶工!
上回说到项目的前两个部分:搭建一个简单的服务器端环境;在服务器处理客户端请求的process中加入鉴权的逻辑,即加入auth()方法。
项目V3代码
在服务器处理客户端请求的process鉴权auth后,授权成功后进行后续连接操作,即加入connect()方法。 注意本项目的目标是完成一个代理服务器,所以服务器端会在成功授权后读取并解析客户端的连接请求,解析成功后,服务器端获取到客户端期待连接的目标ip或是目标域名。
此时connect()方法完成了一部分。
项目V4代码
在这part中加入了connect()方法的最后的逻辑,根据之前获得的客户端期待连接的ip或是域名,进行服务器端到目标的连接。
最后这一部分的代码我想了很久:
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
_, _ = io.Copy(dest, reader)
cancel()
}()
go func() {
_, _ = io.Copy(conn, dest)
cancel()
}()
<-ctx.Done()
dest是服务器端拨号目标地址获得的conn类型对象,conn是服务器端接收客户端获得的conn类型对象; reader是conn包装后的reader对象。
我猜这段代码大致的作用应该是开了两个协程完成一个代理通信,第一个可能是把reader中的信息写到dest连接中,服务器端就代理发送请求给目标;第二个可能是把dest传回给conn,把目标响应的内容写到conn中,客户端就能接收到。
这段最让我迷惑的就是这段代码的框架,搜了一下是什么上下文和取消函数,总之应该就是做协程之间的一个并发之类的?其中一个不能执行下去了,就直接取消掉其他协程然后退出嘛。再看看再看看,这几天多看点文档。