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

go中的套接字回显服务器

go中的套接字回显服务器

Go
开心每一天1111 2021-06-02 21:23:09
我正在尝试在 go 中实现一个简单的套接字回显服务器,这是代码:package mainimport (    "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 服务器)。
查看完整描述

2 回答

?
互换的青春

TA贡献1797条经验 获得超6个赞

这是一个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)

    }

}


查看完整回答
反对 回复 2021-06-21
?
绝地无双

TA贡献1946条经验 获得超4个赞

我没有检查它是否是罪魁祸首,但在“技术分析”方面,我注意到您的代码中有一个错误:您将 a 的副本传递sync.Workgroup给echo_srv. 对副本所做的任何更改对原始实例都无效。


将签名更改echo为:


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

然后像这样调用它:


go echo_srv(conn, &wg)

附带说明:_在惯用的 Go 代码名称中间不使用下划线 ( )。惯用名称将是例如。echoSrv反而。


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

添加回答

举报

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