Socket5 Proxy课程小项目 | 青训营笔记

54 阅读3分钟

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

前言

今天是字节青训营后端课程的第一天,第一次课程讲了go的基础语法和三个实战小项目。说实话语法基础内容太紧凑,科班无go基础的刚看了也是一脸懵,感觉这世界还有这样感觉拍拍脑袋就想出语法的语言。但是这应该是课程设计老师的初心吧,善于利用互联网资源自行查漏补缺,所以我也不想深究语法,之后去看看其他佬们总结好的语法知识点过一遍。

紧接着的项目实战彻底把我看懵,尤其是没有网络编程基础的我看到了socket5代理这个项目。课程结束后决定仔细研究下源码,语法上不懂的边查边学,开始!

项目V1代码

V1的代码是简单实现了一下socket编程,模拟服务器端和客户端的操作。

这篇文章写的很好,开头的服务器端代码基本上就跟项目V1代码是一样的!www.cnblogs.com/wdliu/p/928…

HighLight

func process(conn net.Conn) {
   defer conn.Close()
   reader := bufio.NewReader(conn)
   for {
      b, err := reader.ReadByte()
      if err != nil {
         break
      }
      _, err = conn.Write([]byte{b})
      if err != nil {
         break
      }
   }
}

这是项目代码中创建goroutine处理连接的部分。

  1. 不熟悉这个NewReader方法,说的是传入io.Reader包装成一个有缓冲区的bufio.Reader,但是这里传的是net.Conn类型的conn变量,不知道这两个是什么关系。这行代码的内容姑且认为是从与客户端的连接中读取数据吧。

  2. 然后后面把reader变量用ReaderByte方法转成了一个字节数组b(应该是)。“ _, err = conn.Write([]byte{b})”这行代码的作用应该是把数组b写回到连接conn中,这样客户端那边就能看到了,做到了一个回显的作用,但是语法好奇怪。

    搜了一下,b应该是一个byte,然后那一行代码的作用是把b转成了一个byte数组传入,然后之所以一个返回值是 - ,意思应该是不关心这个返回值吧,看了一下第一个返回值是int类型。

项目V2代码

逻辑很简单,在go处理的process函数体中加入验证的逻辑。感觉验证的逻辑很简单:传入一个conn和从conn读到的数据reader;根据授权报文的格式去读reader;读到reader的第一个字节就是socket版本号,第二个就是方法数;第三个就是哪些方法(注意方法数是几,后面就有多少数量的方法的字节数)。

很神奇的是,readbyte和readall的方法,难道read到了就自动把对应的部分丢弃了嘛,每次read都是从上次结束的地方开始的。

因为是简单实现,授权方式就使用最简单的无加密。所以这部分授权的逻辑就是解析reader的过程成功了无error抛出就授权成功。

后面明天更,赶紧把状态找回来,每天玩的时间太多了!