gpt4 book ai didi

sockets - go 中的套接字回显服务器

转载 作者:IT王子 更新时间:2023-10-29 00:38:10 26 4
gpt4 key购买 nike

我正在尝试在 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
Program received signal SIGINT, Interrupt.
runtime.epollwait () at /usr/lib/go/src/pkg/runtime/sys_linux_amd64.s:383
383 RET
(gdb) info goroutines
1 waiting runtime.park
2 syscall runtime.goexit
* 3 syscall runtime.entersyscallblock

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

客户:

package main

import (
"bufio"
"fmt"
"net"
"os"
"strings"
)

func main() {
stdin := bufio.NewReader(os.Stdin)

conn, err := net.Dial("unix", "./sock_srv")
if err != nil {
fmt.Print(err)
return
}
defer conn.Close()

for {
fmt.Print("Enter message to transmit: ")
msg, err := stdin.ReadString('\n')
if err != nil {
fmt.Print(err)
return
}

msg = msg[:len(msg)-1]
if (strings.ToLower(msg) == "quit") || (strings.ToLower(msg) == "exit") {
fmt.Println("bye")
return
}

n, err := conn.Write([]byte(msg))
if err != nil {
fmt.Print(err)
return
}
fmt.Printf("CLIENT: sent %v bytes\n", n)

n, err = conn.Read([]byte(msg))
if err != nil {
fmt.Print(err)
return
}
fmt.Printf("CLIENT: received %v bytes\n", n)

fmt.Println("Received message:", msg)
}
}

最佳答案

这是为您准备的有效 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)
    }
    }

关于sockets - go 中的套接字回显服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17766770/

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