Golang基础第一天 | 青训营笔记

132 阅读7分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记

go基础语言

image.png image.png

简介十分钟

image.png 在golang里面不需要去寻找经过高度优化的第三方库,可以直接用官方库或者基于标准库的第三方来开发高并发,标准库很丰富
代码实现了简单http服务器
核心代码第八行在标准库的http包的路由,把\的路由指向静态文件 监听8080端口,启动服务器
编译结果是静态链接 image.png 云原生组件都是由go是实现的 image.png

入门

image.png image.png goproxy配置好后能加速第三方包 image.png image.png

基础语法

属于mian包,main包是程序入口包,fmt是基础输入输出包 image.png 变量类型 image.png 字符是内置类型,可以用+和=使用,其他和c++类似
变量声明方式 var 名字 类型=..
或者变量名:=.. 常量用const 自动确定类型 image.png if 判断语句没有括号 在内部才有括号 image.png 循环里面用continue和break image.png c++里需要加break,go不需要
switch可以使用任意变量类型,包括使用字符串,结构体,可以省略if else image.png var 变量名[数量]类型 image.png 切片比数组更重要,不同于数组,他是可变数组 s := make([]string,3) 可是可变长度的
切片的append里面,原理存储了一个长度加一个容量和指向数组的指针,如果容量不够会扩容返回一个新的切片
slice里是左闭右开的 image.png hash数组,key-value
map是无序的 image.png slice和map用range遍历index-value,key-value image.png 函数变量类型是后置的 image.png 指针就是对函数里的值修改 image.png 带类型 字段的集合 指针的结构体,可以进行值的修改 image.png 类似类成员函数,带指针可以对成员修改 image.png 用返回值来表示错误信息,可以确定到错误,直接return两个值, image.png 字符串内置函数,对于中文来说一个中文对应多个字符 image.png %v来打印结果 用%#v打印结构体类型 image.png 序列化后变成byte数组,需要用string() 注意输出的age和反序列化的处理 image.png sub做时间段,格式化用2006-01-02 15:04:05的格式来确定自己的格式 image.png 解析字符串,parseint(111,10,64) 111表示字符串,10表示十进制,64表示精度,传0是自动推测 用atoi把字符串转成数字同理itoa相反 image.png os.Args 获取进程的命令行参数 数出来的就是目录加参数 os.getenv获取环境变量 os.setenv写入环境变量 exec.Command快速启动子进程并获取输入输出

实战

image.png image.png image.png 随机生成数字 发现每次数组都是相同的,因为seed的参数一样 image.png 添加时间戳 image.png image.png stdin,stdout,stderro 用stdin来得到,直接操作不方便 bufio用只读流来读取一行,然后去掉换行符 atoi转换数字 image.png 用scanf会更好,因为bufio后面项目会用所以介绍一下 image.png 后面会添加循环 image.png 注意出错是continue image.png 查询单词,并得到建议 原理:第三方api去查询翻译并打印,用go语言发送http请求,解析json,学习代码生成提高开发效率 image.png image.png 尝试抓包看到了post请求,参数是json image.png 介绍一个简单方式,生成请求 image.png image.png curlconverter.com/#go 把curl放入这个网站,同时删除错误 image.png image.png 12行创建httpclient
可以指定参数的timeout,不超时
14行创建post请求,mehtod url data是一个流,流式数据 image.png 输出结果为json
把请求和返回都得到了
接下来需要序列化一个json 构建结构体,并调用json.marshal image.png 结构体主要用了前两个,构造完结构体后,创建了一个结构体变量,然后json一下转化到byte的buf数组,然后转化为byte的data,变成byte流,同时执行结果不变 image.png 解析response,body返回的字典或者map,但是golang一般用结构体来对应response,再反序列化
用代码生成创建json结构体 oktools.net/json2go
把preview结构体放入,直接放入转换的嵌套结构体 image.png image.png image.png 定义dictResponse,并用json.Unmarshal来反序列化,注意要地址符,结果如下 image.png image.png 91-93是防御式编程,需要对response请求判断,StatusCode判断报文
99-102取出想要的字符串 image.png main函数改成query函数,然后通过加入的字符来判断,判断os.Args[1] image.png image.png SOCKS5代理服务器,不能支持翻墙,明文传输,用途内网确保安全性,访问资源麻烦
SOCKS5需要暴露一个端口来访问内部资源,开发爬虫会碰到ip限制,可以去找ip代理池,代理池协议式socks5协议 image.png 代码的最终结果,配置代理,会发现域名加端口 打开网页会输出url域名和端口 image.png 正常访问的网址,不经过代理服务器的话,需要和服务器建立tcp链接,三次握手,握手完成,发送http请求,然后返回http响应
设置代理服务器会变的复杂,首先浏览器和socks5建立tcp连接,然后socks5和真正服务器tcp连接
协商阶段,发送协议版本号,支持认证种类和socks5连接返回浏览器,跳过对认证流程描述,
然后进入请求阶段,包括协议版本号,请求类型,命令代理服务器某个域名和ip进行连接,然后建立与目标的连接
然后就是发送数据,给socks5,socks5发送数据然后响应,接下来式简单实现
image.png 实现简单的TCP echo server 发送啥就回复啥
先监听端口,返回的server,然后server接收请求返回连接,然后用go process里处理连接,是一个子协程
process实现,需要第一步保证最后退出关conn
创建只读流,用for循环来读一个字节,并把字节写入,28行看起来是一个一个字节的读,实际上底层实现是连续的读的
32行 是进行字节转化,用[]byte,写一个字节给服务器 image.png 用nc 连接 输入hello服务器会返回hello image.png 实现协议第一阶段,参数由只读流和tcp连接,浏览器发送报文,读报文并操作读出来,然后按照协议返回一个包给浏览器
process把死循环去掉,然后调用auth函数
认证逻辑:一个包三个字段:协议版本号,methods,第三个是编码,0代表不认证,1代表用户密码
然后读报文,因为单字节可以用readbyte读一个字节,返回版本号,然后再读方法名字,用methodsize创建method缓冲区,然后打印,77行 协议会返回一个包,创建了一个包,返回版本和不需要认证 image.png 结果发现日志是正常答应,但是curl命令是不成功的 image.png 请求阶段代码试图读取浏览器发送的报文,类似auth的conncet函数 第一个地段是version 5,command表示请求,第三个字段是保留字段默认为0,第四个字段是atype目标对峙类型,ipv4,ipv6或者域名,然后根据类型分配长度,最后一个是端口号
读取四个字段,总共四个字节,如果ipv4还是直接放,如果是host要读取长度,然后再换
再用binary来解析整形数字,然后打印地址和端口号,回包就是,一般不使用 image.png 结果可以看到正常打印出来访问的ip地址和端口,这样可以实现连接双向转发数据 image.png 使用完后就可以建立tcp连接,连接后第一时间关闭连接,接下来建立浏览器和服务器的双向数据转发,过程是copy函数从src读数据,写到dst,双向转发需要两个go routine image.png 第一个路径从用户浏览器拷贝到到底层服务器
第二个是底层服务器到用户浏览器
当前问题需要等待任意一个方向关闭连接菜种植,所以需要一个context机制,等待Ctx.done结束 只有调用cancel()才能关闭连接 image.png 最后可以用curl命令测试一下,日志会输出协商发送的东西 也可以用浏览器安装switchormega插件,新建一个情景模式,代理服务器选socks5,端口写1080,然后点击应用选项,再点击小圈圈,流量会通过显示 image.png