这是我参与「第五届青训营 」笔记创作活动的第1天 1.1什么是Go语言
1.高性能、高并发
2.语法简单、学习曲线平缓
3.丰富的标准库
4.完善的工具链
5.静态链接
6.快速编译
7.跨平台
8.垃圾回收
实践练习例子:
猜谜游戏
在学习这个例子的时候我复习了Go语言的很多基础语法。
不仅如此,在完成这个例子的课后习题时,也就是第一道题,我一开始使用fmt.Scanf()进行代码简化,遇到了一些问题,循环总是会多次进行,并且第二次的guess值一直是0。我思考了一下,并且查阅了一些资料,发现原来是fmt.Scanf()会把输入数字之后的空格也放入缓存区里,所以缓存区会有两个东西,循环也就进行了两次。解决方法就是在format里面手动加一个\n来吃掉这个空格就可以了。
本来想用fmt.Scan()来代替,但转念一想可能这个作业题目就是为了让我们知道fmt.Scanf()的这个特性,于是就着手去解决了。
在线词典
在学习这个例子的时候了解到了如何手动抓包的基本知识。
当然,现在有很多可以自动抓包的工具,本人会在后续的学习过程中逐渐了解和使用。
在完成这个实践任务的相关课后习题的时候,我遇到了一些问题,在例子中给出了适合于彩云翻译的结构体以及JSON解析,但是对于其他的翻译网站没有给出,我尝试照猫画虎,但是失败了,我觉得可能是需要查找更多的资料,或者自己手写一个适合于其他翻译网站的内容。
同时,也接触到了两个很好用的网站:
在实践的过程中,我了解到bash和cmd的curl是不一样的,我用bash的curl成功生成了代码。
在通过json生成结构体的时候,我了解到如果不需要对这个返回结果做很多精细的操作,可选择转换嵌套来让生成的代码更加紧凑。
SOCKS5代理
前提:socks5协议都是明文传输
用途:
某些企业的内网为了确保安全性,有很严格的防火墙策略,副作用就是访问某些资源很麻烦,
socks5相当于在防火墙上开了个口子,让授权的用户可以通过单个端口去访问内部的所有资源。
在爬虫的时候,爬取过程中很容易会遇到IP访问频率超过限制,这个时候很多人就会去上网找一些代理IP池,这些代理IP池里的很多代理协议就是socks5。
启动后的效果:
- 启动,然后在浏览器里面配置使用这个代理,打开网页;
- 代理服务器的日志,会打印出你访问的网站的域名 or IP,这说明我们的网络流量是通过这个代理服务器的;
- 我们也能在命令行去测试我们的代理服务器,
curl -socks5 <代理服务器地址>,后面加一个可访问的URL,如果工作正常,则curl命令就会正常返回。
原理:
正常浏览器访问一个网站,如果不经过代理服务器的:
- 先和对方的网站建立TCP连接
- 然后三次握手
- 然后发起HTTP请求
- 然后服务返回HTTP响应。
如果设置代理服务器,流程变复杂,变为:
-
首先浏览器和socks5代理建立TCP连接,代理再和真正的服务器建立TCP连接,分为四个阶段
-
握手阶段:浏览器会向socks5代理发送请求,内容包括一个协议的版本号,还有支持的认证的种类,socks5服务器会选中一个认证方式,返回给浏览器。如果返回的是00的话就代表不需要认证,返回其他类型的话会开始认证流程。
-
认证阶段:有点复杂暂略。
-
请求阶段:认证通过后浏览器会向socks5服务器发起请求,主要信息还是包括版本号和请求的类型,一般主要是connection请求,就代表代理服务器和要某个域名或者某个IP地址某个端口建立TCP连接。代理服务器收到响应后,会真正和后端服务器建立连接,然后返回一个响应。
-
relay阶段:此时浏览器会发送正常请求,然后代理服务器收到请求后,会直接把请求转换到真正的服务器上。然后如果真正的服务器以后返回响应的话,那么也会把请求转发到浏览器这边。然后实际上代理服务器并不关心流量的细节,可以是HTTP流量,也可以是其他TCP流量。这个就是socks5协议的工作原理。
在不同目录下新建两个 main 函数呢
我的几个疑问:
- 不同目录下的 go 代码文件,是否可以同属于 package main?
- 不同目录下的 main 函数,是否可以 go build 一键生成多个二进制文件?
- 多个 main 入口文件,是否需要多个 go.mod?
测试方法:
- 新建一个目录,例如 cmd,将 main.go 移动到 cmd 目录下
这种方法确实可行。
测试结果:
- 在根目录下执行 go build, 只会生成根目录下 main 函数对应的二进制文件。cmd 目录下的 main.go 没有被编译。
- 到 cmd 下执行 go build,可以成功编译,并运行。
- 两个不同的入口文件确实可以同属于 package main.
到目前为止,独立一个 cmd 目录已经满足了我当前项目的需求。