为了账号安全,请及时绑定邮箱和手机立即绑定

Go 中的双向连接

Go 中的双向连接

Go
斯蒂芬大帝 2021-06-09 17:46:09
我正在尝试在 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.")}提前致谢。
查看完整描述

1 回答

?
当年话下

TA贡献1890条经验 获得超9个赞

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


文档显示了一个小例子:


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...")

            }

        }

    }

}

此外,您可能应该使用 packagelog而不是fmt您的日志消息(但这在这里无关紧要)。


了解这一切如何工作的一个好地方是在此处浏览默认http服务器的实现。


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


LOOP:

    Send data (e.g. encoder.Encode)

    Receive data (e.g. decoder.Decode)

    if problem or termination -> break out of loop

END

close connection


查看完整回答
反对 回复 2021-06-28
  • 1 回答
  • 0 关注
  • 164 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信