笔记标题 | 青训营笔记

42 阅读3分钟

实际上的VPN代理也是类似的效果,只不过使用的不是socks5这种明文协议,明文协议一个缺点一是数据的安全性不能得到保证,二是不能阻挡被墙的命运因此不能用作VPN。

代理服务器的流程: client--建立连接-->proxy server--认证成功-->client(具体使用协议需要自己实现,学协议这么久也是第一次学到如何去对协议进行定义、读取、认证) 之后可在网页使用OMG开启服务器代理,所有的数据包就会都通过代理服务器进行转发,由于是本地实现代理服务程序,所以socket是127.0.0.1:1080.同样的也可以使用将clf的配置更新到服务器中,只需更新对应端口,不过好像直接用clf的rule模式就可以,具体差别还不太清楚。

项目的实现应该一步一步的,从简单写起,保证每一部分的基本功能的到实现之后在进行功能的扩充改写,否则一旦后期出现问题找bug是很痛苦的。

proxy服务器的实现: 使用net.listen监听本地端口,这里的IP无论是在本地还是后期在其他服务器上实现应该都是127.0.0.1 ,需要改变的的client发送的IP应该是服务器的公网地址。 将监听返回的server句柄放到一个死循环中,不断对请求进行接收,并把接受的client请求放到一个gorouting里执行下一步操作,实现高并发。 goroutine 的process函数用于对接受的请求进行处理。 在处理过程中需要实现认证连接两个功能 认证用于认证协议,链接用于实现双向的数据传输。

我们在程序开头通过定义一些常量字段用于协议的认证。在认证和链接时传输的参数分别是一个reader(链接的)和链接本身(注意需要关闭),一个用于读取内容,一个用于数据传输。reader的好处是你每次可以读取一个字节,下次读取时会继续从上次的部分读。认证成功后,使用conn.Write返回一些数据表明认证已经完成,我们应该在某一过程间函数完成任务时打印日志,表明之前的函数功能都是正常的,以防止程序过大导致的调试困难。

链接功能用于建立双向链接,进行数据的通信。协议认证成功后,读取相应的IP和PORT, port:=binary.BigEndian.Uint16(buf[:2]) 打印连接成功日志,并写回读取的协议、IPtype、IP、PORT等。

使用net.Dial("protocal",socket)与目标主机建立链接(注意需要关闭),打印链接日志。由于是双向链接,需要启动两个goroutine。

需要等待两个goroutine执行完毕或者出错的时候在关闭connect,使用context机制进行goroutine保护。

question:copy(dest,reader) 这里的reader为什么不是conn

作者:用户6246279551370
链接:juejin.cn/post/719063…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。