当前位置: 首页 > news >正文

四平网站优化做直播app的公司

四平网站优化,做直播app的公司,123上网之家网址,搜狗竞价#x1f442; Take me Hand Acoustic - Ccile Corbel - 单曲 - 网易云音乐 第3个小项目有问题#xff0c;不能在Windows下跑#xff0c;懒得去搜Linux上怎么跑了#xff0c;已经落下进度了.... 目录 #x1f633;前言 #x1f349;Go两小时 #x1f511;小项目实战 … Take me Hand Acoustic - Cécile Corbel - 单曲 - 网易云音乐 第3个小项目有问题不能在Windows下跑懒得去搜Linux上怎么跑了已经落下进度了.... 目录 前言 Go两小时 小项目实战 猜数字游戏 在线词典 代码1  --  抓包 代码2  --  生成request body  代码3  --  解析 response body 代码4  --  打印结果 代码6  --  完整代码 cmd测试 Socks5代理服务器 介绍 原理 TCP echo server auth 请求阶段 relay阶段 Hertz框架 前言 注意run时要点func main()左边的绿色▲而不是右上方的虫子和▲ 注意2~ 一个文件夹下只能有一个main.go文件比如这样 学Go除了字节内部课还需要一套B站全流程的新手入门视频只是内部课的话节奏比较快虽然也是有视频事无巨细地教但有些点小白还是不懂的需要到B站新手视频处查阅需要一遍又一遍bingGoogle百度GPTstackOverFlowyoutubeB站一共7个工具记好了加上算法群项目群在职群....效率不会低的 还需要很多文档... Go两小时 注意先安装GolandGit弄个Github学生认证免费使用 跟着敲一遍182行代码先有个印象 从 Java 的角度初识 Go 语言 青训营笔记 - HikariLans Blog (minecraft.kim) 跟着敲完180行入门代码还不过瘾的话再跟这个5小时教程巩固一下基础 【golang教学】第二章golang的基础知识——结构包变量初探1010工作室出品_哔哩哔哩_bilibili 代码 -- 复制可运行 package mainimport (errorsfmttime )import (_ errors )// 错误处理 func findUser(users []user, name string) (v *user, err error) {for _, u : range users {if u.name name {return u, nil}}return nil, errors.New(not found) }func add(a int, b int) int {return a b //函数要写在主函数外 }func add2(n int) {n 2 }func add2ptr(n *int) {*n 2 }type user struct {name stringpassword string }// 检查用户密码是否匹配 func (u user) checkPassword(password string) bool {return u.password password }// 充值密码, 指针结构体 func (u *user) resetPassword(password string) {u.password password }func main() {var a int 1var b, c int 1, 3fmt.Println(a, b, c)if 7%2 0 {fmt.Println(7 is even)} else {fmt.Println(7 is odd)}t : 2 //声明并初始化一个新的变量switch t {case 0, 1:fmt.Println(zero or one)case 2:fmt.Println(two)default:fmt.Println(other)}tt : time.Now()switch {case tt.Hour() 12:fmt.Println(it is before noon)default:fmt.Println(it is after noon)}v : 42switch v {case 100:fmt.Println(100)fallthroughcase 42:fmt.Println(42)fallthroughcase 1:fmt.Println(1)fallthroughdefault:fmt.Println(default)}for j : 7; j 9; j {fmt.Println(j)}i : 1for i 3 {fmt.Println(i)i i 1}nums : []int{2, 3, 4}sum : 0for idx, num : range nums {fmt.Println(range to index, idx)sum num}fmt.Println(sum:, sum)//遍历map, 得到 键 k 值 vm : make(map[string]int)m[hello] 0m[world] 1//if key and value both neededfor k, v : range m {fmt.Printf(%v %v\n, k, v)}//or only need keyfor k : range m {fmt.Printf(%v \n, k)}var aa [5]intfor i : 0; i 3; i {aa[i] ifmt.Println(aa[i])}bb : [5]int{1, 2, 3, 4, 5}fmt.Println(bb[4])var twoD [2][3]intfmt.Println(twoD[1][2])//切片s : make([]string, 3, 10)s[0] as[1] bs[2] cfor i : 0; i 3; i {fmt.Println(s[i])}//映射mm : map[string]int{one: 111, two: 2}fmt.Println(len(mm), mm[one], mm[wtf])fmt.Println(add(10, 2))n : 5add2(n) //not workingfmt.Println(n) // 5add2ptr(n) //workingfmt.Println(n) // 7//初始化结构体cc : user{name: wang, password: 1024}fmt.Printf(%v\n, cc) //{name:wang password:1024}fmt.Println(cc.name)fmt.Println(cc.password)//调用密码匹配结构体函数var dd userdd.resetPassword(2048)fmt.Println(dd.checkPassword(2048)) //true//调用错误函数u, err : findUser([]user{{wang, 1024}}, wang)if err ! nil {fmt.Println(err)return}fmt.Println(u.name)if u, err : findUser([]user{{wang, 1024}}, li); err ! nil {fmt.Println(err) //not foundreturn} else {fmt.Println(u.name)} }小项目实战 猜数字游戏 描述 猜数字猜大猜小了都会有提示知道最终猜中结束循环 如果输入不合法字符串不能转化为整型就会提示Invalid Input 代码 // 数字猜测游戏 package mainimport ( //导入第3方包bufiofmt_ fmt //format包, 输入输出字符串math/rand_ math/randosstrconv_ strconvstringstime_ time )func main() {maxNum : 100//Goland 1.15后不需要随机数种子, 会自动调用math/rand包的函数rand.Seed(time.Now().UnixNano())secretNumber : rand.Intn(maxNum) //生成0~100随机数//fmt.Println(The secret number is , secretNumber)fmt.Println(Please input your guess)reader : bufio.NewReader(os.Stdin) //os.Stdin得到Stdin文件, bufio.NewReader转成只读的流for {input, err : reader.ReadString(\n) //ReadString读入一行输入if err ! nil {fmt.Println(An error occured while reading input. Please try again, err)continue}input strings.TrimSuffix(input, \r\n) //strings包的TrimSuffix函数去掉回车符和换行符guess, err : strconv.Atoi(input) //Atoi转数字if err ! nil {fmt.Println(Invalid input. Please enter an integer value)continue}fmt.Println(Your guess is, guess)if guess secretNumber {fmt.Println(Your guess is bigger than the secret number. Please try again)} else if guess secretNumber {fmt.Println(Your guess is smaller than the secret number. Please try again)} else {fmt.Println(Correct, you Legend)break}} }cmd测试 在线词典 描述 先说下几个代码生成的工具网址 1Convert curl commands to Go (curlconverter.com) 用于将 cURL 命令转换为 Go 代码也可以是其他语言 cURL 是一个常用的命令行工具用于发送 HTTP 请求并获取响应 将 cURL 命令转换为相应的编程语言代码可以方便地在代码中执行相同的 HTTP 请求 2JSON转Golang Struct - 在线工具 - OKTools 这个更好用支持20多种转换 彩云小译 - 在线翻译 (caiyunapp.com) 上面网址打开开发者工具 右键nameCopyCopy as Curlbash粘贴到下面网址 就转化成Go代码了(或者其他语言) Convert curl commands to code 1用Go语言发送http请求解析json 代码1  --  抓包 输出一长串 json 字符 package mainimport (fmtiolognet/httpstrings )func main() {client : http.Client{}//字符串data转成流var data strings.NewReader({trans_type:en2zh,source:good})//1.创建请求//创建http的POST请求, 第二个参数是urlreq, err : http.NewRequest(POST, https://api.interpreter.caiyunai.com/v1/dict, data)if err ! nil {log.Fatal(err)}//2.设置请求头req.Header.Set(authority, api.interpreter.caiyunai.com)req.Header.Set(accept, application/json, text/plain, */*)req.Header.Set(accept-language, zh-CN,zh;q0.9,en;q0.8,en-GB;q0.7,en-US;q0.6)req.Header.Set(app-name, xy)req.Header.Set(content-type, application/json;charsetUTF-8)req.Header.Set(device-id, 6febce1e00ffc1f9e33ddd0354386064)req.Header.Set(origin, https://fanyi.caiyunapp.com)req.Header.Set(os-type, web)req.Header.Set(os-version, )req.Header.Set(referer, https://fanyi.caiyunapp.com/)req.Header.Set(sec-ch-ua, Not/A)Brand;v99, Microsoft Edge;v115, Chromium;v115)req.Header.Set(sec-ch-ua-mobile, ?0)req.Header.Set(sec-ch-ua-platform, Windows)req.Header.Set(sec-fetch-dest, empty)req.Header.Set(sec-fetch-mode, cors)req.Header.Set(sec-fetch-site, cross-site)req.Header.Set(user-agent, Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.183)req.Header.Set(x-authorization, token:qgemv4jr1y38jyq6vhvi)//3.发起请求resp, err : client.Do(req)if err ! nil {log.Fatal(err) //请求失败退出进程}defer resp.Body.Close() //拿到请求后通过defer关闭流bodyText, err : io.ReadAll(resp.Body)if err ! nil {log.Fatal(err)}fmt.Printf(%s\n, bodyText) //打印json字符串 }由于最终要通过变量输入而不是 json 字符串输入所以需要 json 实例化 代码2  --  生成request body  实例化一个 json需要构造一个结构体使结构体的名字和 json 的结构一一对应再调用 json.Marshal()函数举例 package mainimport (encoding/jsonfmt )type userInfo struct {Name stringAge intHobby []string }func main() {a : userInfo{Name: wang, Age: 18, Hobby: []string{Golang, TypeScript}}buf, err : json.Marshal(a)//...buf, err json.MarshalIndent(a, , \t)... } 修改后的代码 package mainimport (bytesencoding/jsonfmtiolognet/http )// 构造结构体 type DictRequest struct {TransType string json:trans_type //翻译Source string json:source //原文本UserID string json:user_id //用户ID }func main() {client : http.Client{}//new一个结构体变量并初始化字段名request : DictRequest{TransType: en2zh, Source: good}buf, err : json.Marshal(request) //json.Marshal实例化request//request转bytes数组var data bytes.NewReader(buf)//1.创建请求//创建http的POST请求, 第二个参数是urlreq, err : http.NewRequest(POST, https://api.interpreter.caiyunai.com/v1/dict, data)if err ! nil {log.Fatal(err)}//2.设置请求头req.Header.Set(authority, api.interpreter.caiyunai.com)req.Header.Set(accept, application/json, text/plain, */*)req.Header.Set(accept-language, zh-CN,zh;q0.9,en;q0.8,en-GB;q0.7,en-US;q0.6)req.Header.Set(app-name, xy)req.Header.Set(content-type, application/json;charsetUTF-8)req.Header.Set(device-id, 6febce1e00ffc1f9e33ddd0354386064)req.Header.Set(origin, https://fanyi.caiyunapp.com)req.Header.Set(os-type, web)req.Header.Set(os-version, )req.Header.Set(referer, https://fanyi.caiyunapp.com/)req.Header.Set(sec-ch-ua, Not/A)Brand;v99, Microsoft Edge;v115, Chromium;v115)req.Header.Set(sec-ch-ua-mobile, ?0)req.Header.Set(sec-ch-ua-platform, Windows)req.Header.Set(sec-fetch-dest, empty)req.Header.Set(sec-fetch-mode, cors)req.Header.Set(sec-fetch-site, cross-site)req.Header.Set(user-agent, Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.183)req.Header.Set(x-authorization, token:qgemv4jr1y38jyq6vhvi)//3.发起请求resp, err : client.Do(req)if err ! nil {log.Fatal(err) //请求失败退出进程}defer resp.Body.Close() //拿到请求后通过defer关闭流bodyText, err : io.ReadAll(resp.Body)if err ! nil {log.Fatal(err)}fmt.Printf(%s\n, bodyText) //打印json字符串 }代码3  --  解析 response body 将一大串 response 解析获取里面的几个字段 按 request 的方式构造结构体结构体字段和返回的 response 一一对应再将返回的 json 字符串反序列化到结构体里 但是这里的字段非常复杂这时需要一个 json 转Go Struct 的工具 JSON转Golang Struct - 在线工具 - OKTools 整块代码粘贴过去 右键copy value转换-嵌套 type DictResponse struct {Rc int json:rcWiki struct {} json:wikiDictionary struct {Prons struct {EnUs string json:en-usEn string json:en} json:pronsExplanations []string json:explanationsSynonym []string json:synonymAntonym []string json:antonymWqxExample [][]string json:wqx_exampleEntry string json:entryType string json:typeRelated []interface{} json:relatedSource string json:source} json:dictionary } 代码4  --  打印结果 var dictResponse DictResponse //定义DictResponse变量//json.Unmarshal将bodyText解析为结构体变量的值err json.Unmarshal(bodyText, dictResponse) // 写入结构体if err ! nil {log.Fatal(err)}fmt.Printf(%#v\n, dictResponse) //%#v 打印结构体 详细值 输出 但是我们只需要 音标(prons) 和 解释(explanations) 代码5  --  完善结果 代码6  --  完整代码 package mainimport (bytesencoding/jsonfmtiolognet/httpos )// 构造结构体 type DictRequest struct {TransType string json:trans_type //翻译Source string json:source //原文本UserID string json:user_id //用户ID }// 结构体嵌套 type DictResponse struct {Rc int json:rcWiki struct {} json:wikiDictionary struct {Prons struct {EnUs string json:en-usEn string json:en} json:pronsExplanations []string json:explanationsSynonym []string json:synonymAntonym []string json:antonymWqxExample [][]string json:wqx_exampleEntry string json:entryType string json:typeRelated []interface{} json:relatedSource string json:source} json:dictionary }func query(word string) {client : http.Client{}//new一个结构体变量并初始化字段名//request : DictRequest{TransType: en2zh, Source: good} //固定字符串request : DictRequest{TransType: en2zh, Source: word} //变量wordbuf, err : json.Marshal(request) //json.Marshal实例化request//request转bytes数组var data bytes.NewReader(buf)//1.创建请求//创建http的POST请求, 第二个参数是urlreq, err : http.NewRequest(POST, https://api.interpreter.caiyunai.com/v1/dict, data)if err ! nil {log.Fatal(err)}//2.设置请求头req.Header.Set(authority, api.interpreter.caiyunai.com)req.Header.Set(accept, application/json, text/plain, */*)req.Header.Set(accept-language, zh-CN,zh;q0.9,en;q0.8,en-GB;q0.7,en-US;q0.6)req.Header.Set(app-name, xy)req.Header.Set(content-type, application/json;charsetUTF-8)req.Header.Set(device-id, 6febce1e00ffc1f9e33ddd0354386064)req.Header.Set(origin, https://fanyi.caiyunapp.com)req.Header.Set(os-type, web)req.Header.Set(os-version, )req.Header.Set(referer, https://fanyi.caiyunapp.com/)req.Header.Set(sec-ch-ua, Not/A)Brand;v99, Microsoft Edge;v115, Chromium;v115)req.Header.Set(sec-ch-ua-mobile, ?0)req.Header.Set(sec-ch-ua-platform, Windows)req.Header.Set(sec-fetch-dest, empty)req.Header.Set(sec-fetch-mode, cors)req.Header.Set(sec-fetch-site, cross-site)req.Header.Set(user-agent, Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.183)req.Header.Set(x-authorization, token:qgemv4jr1y38jyq6vhvi)//3.发起请求resp, err : client.Do(req)if err ! nil {log.Fatal(err) //请求失败退出进程}defer resp.Body.Close() //拿到请求后通过defer关闭流bodyText, err : io.ReadAll(resp.Body)if err ! nil {log.Fatal(err)}if resp.StatusCode ! 200 { //记录错误信息并终止执行, 便于排查问题log.Fatal(bad StatusCode:, resp.StatusCode, body, string(bodyText))}var dictResponse DictResponse //定义DictResponse变量//json.Unmarshal将bodyText解析为结构体变量的值err json.Unmarshal(bodyText, dictResponse) // 写入结构体if err ! nil {log.Fatal(err)}fmt.Println(word, UK:, dictResponse.Dictionary.Prons.En, US:, dictResponse.Dictionary.Prons.EnUs)for _, item : range dictResponse.Dictionary.Explanations {fmt.Println(item) //range遍历数组每个元素并打印} }func main() {if len(os.Args) ! 2 { //后面没有接一个单词打印错误并退出fmt.Fprintf(os.Stderr, usage: simpleDict WORD example: simpleDict hello)os.Exit(1)}word : os.Args[1] //后面接一个单词打印单词query(word) }cmd测试 Socks5代理服务器 介绍 原理 SOCKS5代理服务器充当客户端和目标服务器之间的中介。它接收来自客户端的请求并将其转发到目标服务器然后将目标服务器的响应转发回客户端。这样客户端可以通过代理服务器访问目标服务器上的资源同时实现了客户端与目标服务器之间的隔离和隐藏 客户端连接到SOCKS5代理服务器客户端首先与SOCKS5代理服务器建立连接。这个连接是直接建立的不会经过目标服务器 客户端发送代理请求一旦与代理服务器建立连接客户端就会向代理服务器发送代理请求。请求中包含要连接的目标服务器的地址、端口号和认证信息如果需要 代理服务器建立连接代理服务器收到代理请求后会解析其中的目标服务器地址和端口号并尝试与目标服务器建立连接 代理服务器与目标服务器交换数据一旦代理服务器成功地与目标服务器建立连接它会在客户端和目标服务器之间进行数据中转。代理服务器接收来自客户端的数据并将其发送给目标服务器相应地它从目标服务器接收数据并将其发送回客户端 数据传输完成当数据传输完成后可以根据具体的需求来决定是否保持连接或断开连接 TCP echo server Socks5代理服务器较为复杂我们先从简化版本 TCP echo server开始 TCP回显服务器TCP echo server是一种基于TCP协议的网络服务器它接收客户端发送的数据并将其原封不动地返回给客户端 不挣扎了检索了2小时都没跑通最后群里一问这玩意没法在Windows跑 所以下面只是粘贴代码上去不作解释和运行测试 package mainimport (bufiolognet )func main() {server, err : net.Listen(tcp, 127.0.0.1:1080)if err ! nil {panic(err)}for {client, err : server.Accept()if err ! nil {log.Printf(Accept failed %v, err)continue}go process(client)} }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}} }auth ... package mainimport (bufiofmtiolognet )const socks5Ver 0x05 const cmdBind 0x01 const atypeIPV4 0x01 const atypeHOST 0x03 const atypeIPV6 0x04func main() {server, err : net.Listen(tcp, 127.0.0.1:1080)if err ! nil {panic(err)}for {client, err : server.Accept()if err ! nil {log.Printf(Accept failed %v, err)continue}go process(client)} }func process(conn net.Conn) {defer conn.Close()reader : bufio.NewReader(conn)err : auth(reader, conn)if err ! nil {log.Printf(client %v auth failed:%v, conn.RemoteAddr(), err)return}log.Println(auth success) }func auth(reader *bufio.Reader, conn net.Conn) (err error) {// ------------------------// |VER | NMETHODS | METHODS |// ------------------------// | 1 | 1 | 1 to 255 |// ------------------------// VER: 协议版本socks5为0x05// NMETHODS: 支持认证的方法数量// METHODS: 对应NMETHODSNMETHODS的值为多少METHODS就有多少个字节。RFC预定义了一些值的含义内容如下:// X’00’ NO AUTHENTICATION REQUIRED// X’02’ USERNAME/PASSWORDver, err : reader.ReadByte()if err ! nil {return fmt.Errorf(read ver failed:%w, err)}if ver ! socks5Ver {return fmt.Errorf(not supported ver:%v, ver)}methodSize, err : reader.ReadByte()if err ! nil {return fmt.Errorf(read methodSize failed:%w, err)}method : make([]byte, methodSize)_, err io.ReadFull(reader, method)if err ! nil {return fmt.Errorf(read method failed:%w, err)}log.Println(ver, ver, method, method)// ------------// |VER | METHOD |// ------------// | 1 | 1 |// ------------_, err conn.Write([]byte{socks5Ver, 0x00})if err ! nil {return fmt.Errorf(write failed:%w, err)}return nil }请求阶段 ... package mainimport (bufioencoding/binaryerrorsfmtiolognet )const socks5Ver 0x05 const cmdBind 0x01 const atypeIPV4 0x01 const atypeHOST 0x03 const atypeIPV6 0x04func main() {server, err : net.Listen(tcp, 127.0.0.1:1080)if err ! nil {panic(err)}for {client, err : server.Accept()if err ! nil {log.Printf(Accept failed %v, err)continue}go process(client)} }func process(conn net.Conn) {defer conn.Close()reader : bufio.NewReader(conn)err : auth(reader, conn)if err ! nil {log.Printf(client %v auth failed:%v, conn.RemoteAddr(), err)return}err connect(reader, conn)if err ! nil {log.Printf(client %v auth failed:%v, conn.RemoteAddr(), err)return} }func auth(reader *bufio.Reader, conn net.Conn) (err error) {// ------------------------// |VER | NMETHODS | METHODS |// ------------------------// | 1 | 1 | 1 to 255 |// ------------------------// VER: 协议版本socks5为0x05// NMETHODS: 支持认证的方法数量// METHODS: 对应NMETHODSNMETHODS的值为多少METHODS就有多少个字节。RFC预定义了一些值的含义内容如下:// X’00’ NO AUTHENTICATION REQUIRED// X’02’ USERNAME/PASSWORDver, err : reader.ReadByte()if err ! nil {return fmt.Errorf(read ver failed:%w, err)}if ver ! socks5Ver {return fmt.Errorf(not supported ver:%v, ver)}methodSize, err : reader.ReadByte()if err ! nil {return fmt.Errorf(read methodSize failed:%w, err)}method : make([]byte, methodSize)_, err io.ReadFull(reader, method)if err ! nil {return fmt.Errorf(read method failed:%w, err)}// ------------// |VER | METHOD |// ------------// | 1 | 1 |// ------------_, err conn.Write([]byte{socks5Ver, 0x00})if err ! nil {return fmt.Errorf(write failed:%w, err)}return nil }func connect(reader *bufio.Reader, conn net.Conn) (err error) {// ------------------------------------------// |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |// ------------------------------------------// | 1 | 1 | X00 | 1 | Variable | 2 |// ------------------------------------------// VER 版本号socks5的值为0x05// CMD 0x01表示CONNECT请求// RSV 保留字段值为0x00// ATYP 目标地址类型DST.ADDR的数据对应这个字段的类型。// 0x01表示IPv4地址DST.ADDR为4个字节// 0x03表示域名DST.ADDR是一个可变长度的域名// DST.ADDR 一个可变长度的值// DST.PORT 目标端口固定2个字节buf : make([]byte, 4)_, err io.ReadFull(reader, buf)if err ! nil {return fmt.Errorf(read header failed:%w, err)}ver, cmd, atyp : buf[0], buf[1], buf[3]if ver ! socks5Ver {return fmt.Errorf(not supported ver:%v, ver)}if cmd ! cmdBind {return fmt.Errorf(not supported cmd:%v, cmd)}addr : switch atyp {case atypeIPV4:_, err io.ReadFull(reader, buf)if err ! nil {return fmt.Errorf(read atyp failed:%w, err)}addr fmt.Sprintf(%d.%d.%d.%d, buf[0], buf[1], buf[2], buf[3])case atypeHOST:hostSize, err : reader.ReadByte()if err ! nil {return fmt.Errorf(read hostSize failed:%w, err)}host : make([]byte, hostSize)_, err io.ReadFull(reader, host)if err ! nil {return fmt.Errorf(read host failed:%w, err)}addr string(host)case atypeIPV6:return errors.New(IPv6: no supported yet)default:return errors.New(invalid atyp)}_, err io.ReadFull(reader, buf[:2])if err ! nil {return fmt.Errorf(read port failed:%w, err)}port : binary.BigEndian.Uint16(buf[:2])log.Println(dial, addr, port)// ------------------------------------------// |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |// ------------------------------------------// | 1 | 1 | X00 | 1 | Variable | 2 |// ------------------------------------------// VER socks版本这里为0x05// REP Relay field,内容取值如下 X’00’ succeeded// RSV 保留字段// ATYPE 地址类型// BND.ADDR 服务绑定的地址// BND.PORT 服务绑定的端口DST.PORT_, err conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0})if err ! nil {return fmt.Errorf(write failed: %w, err)}return nil }relay阶段 ... package mainimport (bufiocontextencoding/binaryerrorsfmtiolognet )const socks5Ver 0x05 const cmdBind 0x01 const atypeIPV4 0x01 const atypeHOST 0x03 const atypeIPV6 0x04func main() {server, err : net.Listen(tcp, 127.0.0.1:1080)if err ! nil {panic(err)}for {client, err : server.Accept()if err ! nil {log.Printf(Accept failed %v, err)continue}go process(client)} }func process(conn net.Conn) {defer conn.Close()reader : bufio.NewReader(conn)err : auth(reader, conn)if err ! nil {log.Printf(client %v auth failed:%v, conn.RemoteAddr(), err)return}err connect(reader, conn)if err ! nil {log.Printf(client %v auth failed:%v, conn.RemoteAddr(), err)return} }func auth(reader *bufio.Reader, conn net.Conn) (err error) {// ------------------------// |VER | NMETHODS | METHODS |// ------------------------// | 1 | 1 | 1 to 255 |// ------------------------// VER: 协议版本socks5为0x05// NMETHODS: 支持认证的方法数量// METHODS: 对应NMETHODSNMETHODS的值为多少METHODS就有多少个字节。RFC预定义了一些值的含义内容如下:// X’00’ NO AUTHENTICATION REQUIRED// X’02’ USERNAME/PASSWORDver, err : reader.ReadByte()if err ! nil {return fmt.Errorf(read ver failed:%w, err)}if ver ! socks5Ver {return fmt.Errorf(not supported ver:%v, ver)}methodSize, err : reader.ReadByte()if err ! nil {return fmt.Errorf(read methodSize failed:%w, err)}method : make([]byte, methodSize)_, err io.ReadFull(reader, method)if err ! nil {return fmt.Errorf(read method failed:%w, err)}// ------------// |VER | METHOD |// ------------// | 1 | 1 |// ------------_, err conn.Write([]byte{socks5Ver, 0x00})if err ! nil {return fmt.Errorf(write failed:%w, err)}return nil }func connect(reader *bufio.Reader, conn net.Conn) (err error) {// ------------------------------------------// |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |// ------------------------------------------// | 1 | 1 | X00 | 1 | Variable | 2 |// ------------------------------------------// VER 版本号socks5的值为0x05// CMD 0x01表示CONNECT请求// RSV 保留字段值为0x00// ATYP 目标地址类型DST.ADDR的数据对应这个字段的类型。// 0x01表示IPv4地址DST.ADDR为4个字节// 0x03表示域名DST.ADDR是一个可变长度的域名// DST.ADDR 一个可变长度的值// DST.PORT 目标端口固定2个字节buf : make([]byte, 4)_, err io.ReadFull(reader, buf)if err ! nil {return fmt.Errorf(read header failed:%w, err)}ver, cmd, atyp : buf[0], buf[1], buf[3]if ver ! socks5Ver {return fmt.Errorf(not supported ver:%v, ver)}if cmd ! cmdBind {return fmt.Errorf(not supported cmd:%v, cmd)}addr : switch atyp {case atypeIPV4:_, err io.ReadFull(reader, buf)if err ! nil {return fmt.Errorf(read atyp failed:%w, err)}addr fmt.Sprintf(%d.%d.%d.%d, buf[0], buf[1], buf[2], buf[3])case atypeHOST:hostSize, err : reader.ReadByte()if err ! nil {return fmt.Errorf(read hostSize failed:%w, err)}host : make([]byte, hostSize)_, err io.ReadFull(reader, host)if err ! nil {return fmt.Errorf(read host failed:%w, err)}addr string(host)case atypeIPV6:return errors.New(IPv6: no supported yet)default:return errors.New(invalid atyp)}_, err io.ReadFull(reader, buf[:2])if err ! nil {return fmt.Errorf(read port failed:%w, err)}port : binary.BigEndian.Uint16(buf[:2])dest, err : net.Dial(tcp, fmt.Sprintf(%v:%v, addr, port))if err ! nil {return fmt.Errorf(dial dst failed:%w, err)}defer dest.Close()log.Println(dial, addr, port)// ------------------------------------------// |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |// ------------------------------------------// | 1 | 1 | X00 | 1 | Variable | 2 |// ------------------------------------------// VER socks版本这里为0x05// REP Relay field,内容取值如下 X’00’ succeeded// RSV 保留字段// ATYPE 地址类型// BND.ADDR 服务绑定的地址// BND.PORT 服务绑定的端口DST.PORT_, err conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0})if err ! nil {return fmt.Errorf(write failed: %w, err)}ctx, cancel : context.WithCancel(context.Background())defer cancel()go func() {_, _ io.Copy(dest, reader)cancel()}()go func() {_, _ io.Copy(conn, dest)cancel()}()-ctx.Done()return nil }Hertz框架 资源 看一遍 一文学会 Go 的三个主流开发框架 青训营笔记 - HikariLans Blog (minecraft.kim) 李文周的 【置顶】Go语言学习之路/Go语言教程 | 李文周的博客 (liwenzhou.com) Hertz中文教程 Hertz | CloudWeGo HertzGithub搭建安装学习全流程 hertz/README_cn.md at develop · cloudwego/hertz (github.com)
http://www.pierceye.com/news/52361/

相关文章:

  • 绵阳住房和城市建设局网站官网wordpress 主题 模板 区别
  • 用蜗牛做logo的网站php做用户注册网站
  • 山西笑傲网站建设推广wordpress速度确实差些
  • 手机网站素材网兼职做任务的网站
  • 一些可以做翻译的网站互联网实用技术与网页制作书籍
  • 网站建设部分费用会计科目镇江佳鑫网络科技有限公司
  • 漯河建设网站app平台下载
  • 陕西省住房与城乡建设部网站好看的 网站后台模板
  • 茶社网站开发与设计的开题报告山东网站制作应用
  • 旅行社网站方案企业管理系统哪个好
  • 大业推广网站公司网站建设的视频
  • 个人博客网站建设方案wordpress原生封装app
  • 株洲网站设计外包首选百度云服务器挂网站
  • 在百度上做网站推广效果怎么样怎样在百度上做推广网站
  • 电影影视网站模板免费下载商城网站建设快速服务
  • 网页网站的区别是什么西安建设集团网站
  • 企业查询免费网站包头建设厅官方网站
  • 辽宁网站建设学校本科学院网站建设方案
  • 岳阳建设网站的公司什么是网站开发框架
  • 企业网站网址网站设计与网页制作代码大全
  • 一号建站wordpress图片本地化插件
  • 建设公司营销网站中山市有什么网站推广
  • 网站建设运营合同书整站优化seo
  • 在线网站建设怎么样专业制作标书公司哪家好一点
  • 建设公司网站要注意什么it黑马官网
  • 专业营销型网站建设费用百度seo排名优化提高流量
  • 苏州网络推广公司网站建设如何使用万网主机建设网站
  • 门户网站开发 论文山西专业网站建设价目
  • 界面做的最好的网站软件工程师40岁后的出路
  • 网站建设分金手指排名二九wordpress 新建导航