这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天.
从基础语法开始,就阐明了go语言的特色,高并发,语言简洁
go含有自推导类型:= 省去较为繁琐的var name type语法,但是作用域受限。
for循环可以代替while关键字
for{}
for i:=0;i<num;i++
for i:= range(***){}
较为重要的的有go协程,通道,time模块以及对字符串处理的一系列操作方式。主要在三个实践项目中用到且需要注意。
**1.**猜拳游戏:
MaxNum := 100
rand.Seed(time.Now().UnixNano()) //在随机数之前需要设置随机种子
GetGuss := rand.Intn(MaxNum)
在猜拳游戏中设置随机数之前需要设置随机数种子
input, err := reader.ReadString('\n') //文件读入到第一次界定符所在位置,会将换行一同读入
input = strings.Trim(input, "\r\n")//取出收尾所需要删除的字符,包括换行
当从键盘进行输入读取时,以字符串方式读取,并且reader会将界定符一同读入到input中,所以在后期对字符串转化为数字时存在安全隐患,可能由于换行符造成转化后的结果无法匹配。所以需要对input进一步操作,将多余的转译字符删除。strings.Trim函数会将需要删除的字符在原字符中的头尾部进行删除,如strings.Trim(input, "8"),若输入为888458786188,则输出为4587861。
**2.**写字典:
主要利用工具对程序进行高效编写,首先找到对应翻译网站,选中开发模式,找到对应的文件的POST请求,可以查看具体的请求和响应,
然后根据url进行copy到网站curlconverter.com/go/ 即可快速生成键值对代码
requst := DictRequst{TypeTrans:"en2zh",Source: word}
buf,err := json.Marshal(requst)//json解析得到的结果是byte类型,不是string
if err!=nil{
log.Fatal(err)
}
var data = bytes.NewReader(buf)//字节类型转化为流
req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)//传入流输入
若需要解析对应的json序列化文件则需要创建请求题相应的结构体与请求题名称一一对应。将利用Marshal进行序列化,结构体解析的结果是byte类型,需要转化为可传输的流,byte类型则调用bytes.NewReader(buf)函数转化,string类型调用若需要解析对应的json序列化文件则需要创建请求题相应的结构体与请求题名称一一对应。将利用Marshal进行序列化,结构体解析的结果是byte类型,需要转化为可传输的流,byte类型则调用bytes.NewReader(buf)函数转化,string类型调用若需要解析对应的json序列化文件则需要创建请求题相应的结构体与请求题名称一一对应。将利用Marshal进行序列化,结构体解析的结果是byte类型,需要转化为可传输的流,byte类型则调用bytes.NewReader(buf)函数转化,string类型调用strings.NewReader(buf)函数转化。 最后利用Do函数发起请求。
resp, err := client.Do(req)//客户端发起请求
请求处理完毕后处理响应 类似请求,需要创建json对应的结构体,但是由于该结构体过于庞大,所以借助网址oktools.net/json2go 可以将json响应文件快速转化为go的结构体,
var dictResponse DictResponse
err = json.Unmarshal(bodyText,&dictResponse)
实例化该结构体后开始解析,然后存入对应的dictResponse中,&符号能将数值拷贝到结构体实例中,后期直接调用该结构体内嵌的变量即可获取到服务器响应的值
**3.**socks5代理
代码相对前两个题目较难,主要考察对数据流的读写操作。
// +----+----------+----------+
// |VER | NMETHODS | METHODS |
// +----+----------+----------+
// | 1 | 1 | 1 to 255 |
// +----+----------+----------+
// VER: 协议版本,socks5为0x05
// NMETHODS: 支持认证的方法数量
// METHODS: 对应NMETHODS,NMETHODS的值为多少,METHODS就有多少个字节。RFC预定义了一些值的含义,内容如下:
// X’00’ NO AUTHENTICATION REQUIRED
// X’02’ USERNAME/PASSWORD
主要对协议的理解以及传输的流程进行阐述,该图中ver以及NMETHODS占用1个byte,所以在创建内存读取流数据时只需要读一个字节,而METHODS的大小由NMETHODS决定,找清楚协议之间的关系后需要严格控制流的读取,当流的数据一次需要读取多个时,建立buffer缓冲区,一次可将该缓冲区填满。
ver,err := reader.ReadByte() //首先读取连接内的首个字符,单字符ver
methodSize,err := reader.ReadByte()
method := make([]byte,methodSize)
整体几乎就是对流的读取进行分析,加上服务器与客户端的双向传输,客户端以nc命令可模拟向服务器发起请求,服务端可利用curl -v命令查看自身详细的日志信息。具体代码个人实现起来比较困难,只能继续研读代码,或先深入理解socks5的具体流程以及协议规则。