gpt4 book ai didi

go - Go中的两种方式连接

转载 作者:IT王子 更新时间:2023-10-29 02:34:45 25 4
gpt4 key购买 nike

我正在尝试用 Go 进行简单的控制台聊天,只是为了练习。但是,我不知道如何从服务器发回消息。服务器只是收到一条消息,然后关闭连接。我该如何发送回复?

我一直在搜索并找到有关 websockets 的信息,但我认为它们用于与浏览器交互。

这是服务器的两个功能:

func runServer() {
// Listen on a port
listen, error := net.Listen("tcp", ":8272")

// Handles eventual errors
if error != nil {
fmt.Println(error)
return
}

fmt.Println("Listening in port 8272.")

for {
// Accepts connections
con, error := listen.Accept()

// Handles eventual errors
if error != nil {
fmt.Println(error)
continue
}

fmt.Println("Connection accepted.")

// Handles the connection
go handleConnection(con)
}
}

func handleConnection(con net.Conn) {
fmt.Println("Handling connection.")

var message string

// Decodes the received message
decoder := gob.NewDecoder(con)
error := decoder.Decode(&message)

// Checks for errors
if error != nil {
fmt.Println(error)
} else {
fmt.Println("Received", message)
}

// Closes the connection
con.Close()
fmt.Println("Connection closed.")
}

这是客户端的功能:

func runClient() {
// Connects to server
con, error := net.Dial("tcp", "127.0.0.1:8272")

// Handles eventual errors
if error != nil {
fmt.Println(error)
return
}

fmt.Println("Connected to 127.0.0.1:8272.")

// Sends a message
message := "Hello world"
encoder := gob.NewEncoder(con)
error = encoder.Encode(message)

// Checks for errors
if error != nil {
fmt.Println(error)
}

con.Close()

fmt.Println("Message sent. Connection closed.")
}

提前致谢。

最佳答案

您的con 对象是一个连接,它具有此处描述的ReadWrite 方法:here .您应该在连接上循环,尝试Read 传入数据,然后处理它并(可能)Write 返回服务器响应。 (这里bufferio包之类的可以帮你更方便的处理,这只是底层的ReadWriter接口(interface))

文档显示了一个很小的 ​​example :

go func(c net.Conn) {
// Echo all incoming data.
io.Copy(c, c)
// Shut down the connection.
c.Close()
}(conn)

它只处理第一条消息然后关闭。您可以像这样处理每条传入消息:

go func(c net.Conn) {
// Infinite loop: Get data, copy them and start over
for {
// Echo all incoming data.
io.Copy(c, c)
}
// Shut down the connection.
c.Close()
}(conn)

当然,将 io.Copy 替换为与您的服务器相关的任何内容,因此您的示例将如下所示:

func handleConnection(con net.Conn) {
fmt.Println("Handling connection.")

defer func() {
// Closes the connection
con.Close()
fmt.Println("Connection closed.")
}()

var message string

// Decodes the received message
decoder := gob.NewDecoder(con)
encoder := gob.NewEncoder(con)
for {
error := decoder.Decode(&message)

// Checks for errors
if error != nil {
fmt.Println(error)
// Exit the loop
return
} else {
fmt.Println("Received", message)
// Sending back
if error = encoder.Encode(message); error != nil {
fmt.Println(error)
return
} else {
fmt.Println("Echo'd successfuly ! Waiting for next message...")
}
}
}
}

另外,您可能应该使用包 log 而不是 fmt 来记录您的日志消息(但这在这里无关紧要)。

了解其工作原理的一个好地方是浏览默认 http 服务器的实现 here .

同样,您的客户端应使用相同的模式循环:

LOOP:
Send data (e.g. encoder.Encode)
Receive data (e.g. decoder.Decode)
if problem or termination -> break out of loop
END
close connection

关于go - Go中的两种方式连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18231129/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com