并发|青训营笔记

60 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 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) {

//

}