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