Go 中的双向连接

我正在尝试在 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.")

}

提前致谢。


斯蒂芬大帝
浏览 167回答 1
1回答

当年话下

你的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 loopENDclose connection
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go