这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天
Goroutine
协程:由Go语言本身完成,用户态、轻量级线程、栈空间kb级别
线程:内核态、线程内有多个协程,栈空间mb级别
例:goroutine打印helloworld
其中time.Sleep()睡眠一定时间,time.Second时一个Duration类型,5s应该是5*time.Second
Channel
通过通信实现共享内存:channel
通过共享内存实现通信:要加锁,性能差
make(chan int,2)有缓冲通道,缓冲大小为2
make(chan int)无缓冲通道
A是生产,B是消费。因为实际消费速度可能比生产速度更慢(M比AB慢)所以
dest是有缓冲的channel
临界区加锁
WaitGroup实现同步
wg.Add(d int)计数器+d
wg.Done()计数器-1
wg.Wait()阻塞到计数器为0
socks5服务器
认证阶段
浏览器客户端给代理服务器发送报文,包括版本、客户端允许的认证方法数量、客户端允许的方法编码
例如客户端发送0x05(版本) 0x02(两种) 0x01 0x02(种类)
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, 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)
_, err = conn.Write([]byte{socks5Ver, 0x00}) //这里选择0x00不认证
if err != nil {
return fmt.Errorf("write failed:%w", err)
}
return nil
}
go函数
函数
函数都有两个返回值,一个正常的返回值,一个错误信息返回
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]//ok是m的key是否存在
return v, ok
}
如果不需要错误信息返回
func fun(a int, b int) {
//
}