请问在go中如何实现一边监听客户端连接,一边监听用户在终端输入的命令呢?

go新手,现在利用 go 实现一个在终端聊天的程序,我想请问一下如何实现服务端一边在监听新的连接请求,一边可以和其中的一个客户端聊天呢?我现在写的监听客户端连接的程序会阻塞住,在终端输入内容没反应,一时间没了思路,望大神指点一二,谢谢!

目前代码如下,但是代码一直报错:

package main

import (
    "fmt"
    "os"
)

var recvFromTerminalChan chan string
var recvFromNetChan chan string

func main() {
    go readFromTerminal()

    select {
    case str := <-recvFromTerminalChan:
        go sendCommandToNet(str)
    case str := <-recvFromNetChan:
        go doContentFromNet(str)
    }
}

/**
读取从终端输入的内容
*/
func readFromTerminal() {
    var input string

    for {
        fmt.Scan(&input)
        fmt.Println("input content : ", input)
        recvFromTerminalChan <- input
    }
}

/**
发送内容到网络
*/
func sendCommandToNet(command string) {
    fmt.Println("command : ", command)

    if command == "quit" {
        close(recvFromNetChan)
        close(recvFromNetChan)
        os.Exit(0)
    }

    content := command

    recvFromNetChan <- content
}

/**
处理从网络接受到的数据
*/
func doContentFromNet(content string) {
    fmt.Println("content from net : ", content)
}
阅读 2.5k
2 个回答

技术长进了,自己解决了,不过还希望有大佬能帮我看看我写的代码有什么可以优化的没?

package main

import (
    "fmt"
    "os"
)

var recvFromTerminalChan = make(chan string)
var recvFromNetChan = make(chan string)

func main() {
    go readFromTerminal()

    for {
        select {
        case str := <-recvFromTerminalChan:
            go sendCommandToNet(str)
        case str := <-recvFromNetChan:
            go doContentFromNet(str)
        }
    }
}

/**
读取从终端输入的内容
*/
func readFromTerminal() {
    var input string

    for {
        fmt.Scan(&input)
        fmt.Println("input content : ", input)
        recvFromTerminalChan <- input
    }
}

/**
发送内容到网络
*/
func sendCommandToNet(command string) {
    fmt.Println("command : ", command)

    if command == "quit" {
        close(recvFromTerminalChan)
        close(recvFromNetChan)
        os.Exit(0)
    }

    content := command

    recvFromNetChan <- content
}

/**
处理从网络接受到的数据
*/
func doContentFromNet(content string) {
    fmt.Println("content from net : ", content)
}

开三个 goroutine

  • 循环从终端读输入,放到 sendChan
  • 循环从连接接收信息,放到 recvChan
  • 循环 { 从sendChan拿用户的输入,发送;从recvChan拿接收的消息,写到终端。}

伪代码表示如下,领会精神就行了。

sendChan:=make(chan string)
recvChan:=make(chan string)

go func() {
    for {
        input:=readline()
        sendChan<-input
    }
}()

go func(conn *net.TCPConn) {
    // 从连接里读数据
    for {
        // ...
        recv := reader.ReadBytes()
        recvChannel <- recv
    }
}(*net.TCPConn)

go func() {
    // 发送和打印收到的数据
    select {
    case s:=<-sendChan:
        send(s)
    case r:=<-conn:
        println(r)
    }
}()
推荐问题