插件窝 干货文章 Go语言并发编程:如何同时监听网络连接和终端输入?

Go语言并发编程:如何同时监听网络连接和终端输入?

监听 连接 goroutine 输入 951    来源:    2025-03-13

在Go语言中,你可以使用goroutinechannel来同时监听网络连接和终端输入。以下是一个简单的示例,展示了如何实现这一点。

示例代码

package main

import (
    "bufio"
    "fmt"
    "net"
    "os"
)

func main() {
    // 创建一个channel用于在goroutine之间通信
    connChan := make(chan net.Conn)
    inputChan := make(chan string)

    // 启动一个goroutine监听网络连接
    go func() {
        listener, err := net.Listen("tcp", ":8080")
        if err != nil {
            fmt.Println("Error listening:", err.Error())
            return
        }
        defer listener.Close()

        fmt.Println("Listening on :8080...")
        for {
            conn, err := listener.Accept()
            if err != nil {
                fmt.Println("Error accepting:", err.Error())
                continue
            }
            connChan <- conn
        }
    }()

    // 启动一个goroutine监听终端输入
    go func() {
        reader := bufio.NewReader(os.Stdin)
        for {
            fmt.Print("Enter text: ")
            text, _ := reader.ReadString('\n')
            inputChan <- text
        }
    }()

    // 主goroutine处理来自两个channel的消息
    for {
        select {
        case conn := <-connChan:
            go handleConnection(conn)
        case input := <-inputChan:
            fmt.Println("You entered:", input)
        }
    }
}

// 处理网络连接的函数
func handleConnection(conn net.Conn) {
    defer conn.Close()
    fmt.Println("New connection from:", conn.RemoteAddr().String())

    // 简单的回显服务器
    reader := bufio.NewReader(conn)
    for {
        message, err := reader.ReadString('\n')
        if err != nil {
            fmt.Println("Connection closed:", conn.RemoteAddr().String())
            return
        }
        fmt.Print("Received message: ", string(message))
        conn.Write([]byte("Echo: " + message))
    }
}

代码说明

  1. 网络连接监听

    • 使用net.Listen创建一个TCP监听器,监听在8080端口。
    • 在一个单独的goroutine中,使用listener.Accept()接受新的连接,并将连接对象发送到connChan通道。
  2. 终端输入监听

    • 使用bufio.NewReader(os.Stdin)创建一个读取器来读取终端输入。
    • 在另一个goroutine中,读取用户输入并将其发送到inputChan通道。
  3. 主循环

    • 使用select语句同时监听connChaninputChan
    • 当有新的网络连接时,启动一个新的goroutine来处理该连接。
    • 当有终端输入时,打印输入内容。
  4. 处理连接

    • handleConnection函数处理每个连接,读取客户端发送的消息并回显。

运行示例

  1. 运行程序后,程序会监听8080端口并等待终端输入。
  2. 你可以通过telnet或其他工具连接到localhost:8080,发送消息,服务器会回显消息。
  3. 在终端中输入文本,程序会打印你输入的内容。

总结

通过使用goroutinechannel,你可以轻松地在Go语言中实现同时监听网络连接和终端输入的功能。这种模式非常适合需要同时处理多个I/O操作的并发场景。