go中的套接字回显服务器

我正在尝试在 go 中实现一个简单的套接字回显服务器,这是代码:


package main


import (

    "fmt"

    "net"

    "sync"

)


func echo_srv(c net.Conn, wg sync.WaitGroup) {

    defer c.Close()

    defer wg.Done()


    for {

            var msg []byte


            n, err := c.Read(msg)

            if err != nil {

                    fmt.Printf("ERROR: read\n")

                    fmt.Print(err)

                    return

            }

            fmt.Printf("SERVER: received %v bytes\n", n)


            n, err = c.Write(msg)

            if err != nil {

                    fmt.Printf("ERROR: write\n")

                    fmt.Print(err)

                    return

            }

            fmt.Printf("SERVER: sent %v bytes\n", n)

    }

}


func main() {

    var wg sync.WaitGroup


    ln, err := net.Listen("unix", "./sock_srv")

    if err != nil {

            fmt.Print(err)

            return

    }

    defer ln.Close()


    conn, err := ln.Accept()

    if err != nil {

            fmt.Print(err)

            return

    }

    wg.Add(1)

    go echo_srv(conn, wg)


    wg.Wait()

}

出于某种原因,一旦客户端连接, c.Read() 不会阻止并打印错误消息。所以,我的第一个问题是:在客户端向套接字发送某些内容之前,不应该阻止 c.Read() 吗?


第二:打印错误消息后,服务器不会终止。这是我在 gdb 中执行程序时看到的:


(gdb) run                                                                    

Starting program: src/sockets/server/server                                  

warning: Could not load shared library symbols for linux-vdso.so.1.          

Do you need "set solib-search-path" or "set sysroot"?                        

[Thread debugging using libthread_db enabled]                                

Using host libthread_db library "/usr/lib/libthread_db.so.1".                

[New Thread 0x7fffe7806700 (LWP 28594)]                                      

[New Thread 0x7fffe7005700 (LWP 28595)]                                      

ERROR: read                                                                  

EOF^C                                                                        


我在 Python 和 C 中有类似的回声服务器,它们工作正常。为了完整起见,我还在下面发布了套接字客户端应用程序(它适用于我的 C 和 Python 服务器)。


开心每一天1111
浏览 171回答 2
2回答

互换的青春

这是一个echo_srv为你工作。你也需要@jnml 的建议!实际上分配一些缓冲区来接收 - 你做了一个 0 字节的缓冲区!在EOF上整齐地退出只写收到的字节 msg[:n]func echo_srv(c net.Conn, wg *sync.WaitGroup) {    defer c.Close()    defer wg.Done()    for {        msg := make([]byte, 1000)        n, err := c.Read(msg)        if err == io.EOF {            fmt.Printf("SERVER: received EOF (%d bytes ignored)\n", n)            return        } else  if err != nil {            fmt.Printf("ERROR: read\n")            fmt.Print(err)            return        }        fmt.Printf("SERVER: received %v bytes\n", n)        n, err = c.Write(msg[:n])        if err != nil {            fmt.Printf("ERROR: write\n")            fmt.Print(err)            return        }        fmt.Printf("SERVER: sent %v bytes\n", n)    }}

绝地无双

我没有检查它是否是罪魁祸首,但在“技术分析”方面,我注意到您的代码中有一个错误:您将 a 的副本传递sync.Workgroup给echo_srv. 对副本所做的任何更改对原始实例都无效。将签名更改echo为:func echo_srv(c net.Conn, wg *sync.WaitGroup)然后像这样调用它:go echo_srv(conn, &wg)附带说明:_在惯用的 Go 代码名称中间不使用下划线 ( )。惯用名称将是例如。echoSrv反而。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go