go - 如何编写在 goroutine 中执行的函数来发送和接收消息?

标签 go networking tcp websocket server

我必须编写一个客户端代码,它以字符串的形式从服务器接收消息,并从控制台获取输入以结束发送到服务器的消息。这两个操作应该同时运行。我编写了一个代码来执行这些操作,但不是同时执行这些操作。

这是我当前的代码:

func SocketClient() {
    conn, err := net.Dial("tcp", ":9000")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()
    server_reader := bufio.NewReader(conn)
    input_reader := bufio.NewReader(os.Stdin)
    for {
        // for sending messages
        buff, err := input_reader.ReadString('\n')
        if err != nil {
            log.Fatalln(err)
        }
        conn.Write([]byte(buff))

        // for receiving messages but this won't run until the above has taken input from console
        buff2, err := server_reader.ReadString('\n')
        if err != nil {
            log.Fatalln(err)
        }
        fmt.Println("Received: %s", buff2)
    }
}

buff 从服务器接收传入消息,然后 buff2 从控制台接收传出消息输入,但为了再次接收传入消息,buff2 需要一些输入。我知道这可以使用 channel 、互斥锁等来完成,但由于我对基础知识缺乏了解,所以在使用它们时遇到了问题。

我想实际的代码应该是这样的:

func SocketClient() {
    conn, err := net.Dial("tcp", ":9000")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()
    go func() {
        // for sending messages
    } ()
    go func() {
        // for receiving messages
    } ()
}

如何将输入和输出做成两个独立的goroutines?

最佳答案

直接在 SocketClient 中运行其中一个循环.在 SocketClient 启动的新 goroutine 中运行另一个循环.

func SocketClient() error {
    conn, err := net.Dial("tcp", ":9000")
    if err != nil {
        return err
    }
    defer conn.Close()
    server_reader := bufio.NewReader(conn)
    input_reader := bufio.NewReader(os.Stdin)

    go func() {
        defer conn.Close()

        // This loop will break and the goroutine will exit when the
        // SocketClient function executes conn.Close().

        for {
            buff, err := server_reader.ReadBytes('\n')
            if err != nil {
                // optional: log.Fatal(err) to cause program to exit without waiting for new input from stdin.
                return
            }
            fmt.Printf("Received: %s", buff)
        }
    }()

    for {
        // for sending messages
        buff, err := input_reader.ReadBytes('\n')
        if err != nil {
            return err
        }
        if _, err := conn.Write(buff); err != nil {
            return err
        }
    }
}

使用 bufio.Reader ReadBytes方法而不是 ReadString避免 []byte 之间不必要的转换和 string .

关于go - 如何编写在 goroutine 中执行的函数来发送和接收消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55596417/

相关文章:

file - Go中如何一步返回hash和bytes?

go - 在 Go 中使用指向字符串的指针而不是字符串有什么好处

objective-c - 如何在 MAC 中获取连接的以太网或 WiFi 的 IP 地址

networking - 我可以让 Wireguard VPN 对等点相互通信吗?

linux - 传出 TCP 端口匹配监听端口

delphi - 来自 TCustomWinSocket 的 ReceiveBuf 不适用于缓冲区的动态数组

python - 扭曲忽略从 MUD 客户端发送的数据?

testing - 如何从 "main()"测试 "go test"例程?

go - 在 golang 中,如何覆盖嵌入式结构的方法

java - 如何重新打开关闭的套接字以便将消息发送回客户端