gpt4 book ai didi

go - UDP 永远读取 block

转载 作者:行者123 更新时间:2023-12-01 22:43:48 27 4
gpt4 key购买 nike

我有一个在 Go 中创建的简单 UDP 结构,当我运行以下代码时,它会永远阻塞。作为引用,我的服务器的地址在运行客户端的同一台计算机上运行,​​但服务器监听的端口和地址与客户端绑定(bind)的端口和地址不同。

var client Clientee

client.Create("the address of my server")

err, messages := client.Read() // <-- HERE IT BLOCKS FOREVER
if err != nil { panic(err) }

fmt.Printf("Messages: %s", messages)

这是声明我的结构的代码部分:

package controllers

import (
"fmt"
"net"
"time"
)

const (
BUF_SIZE = 1024
CLIENT_PORT = "4097"
SERVER_PORT = "4096"
)

type Clientee struct {
ClServerAddr *net.UDPAddr
ClLocalAddr *net.UDPAddr
ClConn *net.UDPConn
ClWasShutdown bool
}

// Initialize and connect the Clientee
func (c *Clientee) Create(hostAddr string) error {
var err error

c.ClWasShutdown=false

// Resolve the server's address
c.ClServerAddr, err = net.ResolveUDPAddr("udp", hostAddr+":"+SERVER_PORT)
if err != nil { return err }
fmt.Println("Server addr = ",c.ClServerAddr.String())

// Resolve our local address
c.ClLocalAddr, err = net.ResolveUDPAddr("udp", ":"+CLIENT_PORT)
if err != nil { return err }

// Create the connection
c.ClConn, err = net.ListenUDP("udp", c.ClLocalAddr)
if err != nil { return err }

// Pause
time.Sleep(time.Millisecond*200)

return nil
}

// Send a message to the Server
func (c *Clientee) Send(msg string) error {
_, err := c.ClConn.WriteToUDP([]byte(msg), c.ClServerAddr)
if err!=nil { return err }

return nil
}

// Read messages from the Server
func (c *Clientee) Read() (error, string) {
bfr:=make([]byte, BUF_SIZE) // Make the buffer
n, addr, err := c.ClConn.ReadFromUDP(bfr)
if err!=nil { return err, "" }

// If the message doesn't come from the server, don't return it
if addr.String()!=c.ClServerAddr.String() {
return nil, ""
}

return nil, string(bfr[0:n])
}

// Close the Connection.
func (c *Clientee) Close() error {
return c.ClConn.Close()
}

最佳答案

ReadFromUDP 将阻塞,直到收到东西。 docs推荐您到ReadFrom上面写着“ReadFrom 实现了 PacketConn ReadFrom 方法。”。看着PacketConn文档,您会发现以下内容:

ReadFrom reads a packet from the connection, copying the payload into p. It returns the number of bytes copied into p and the return address that was on the packet. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered. Callers should always process the n > 0 bytes returned before considering the error err.

ReadFrom can be made to time out and return an Error with Timeout() == true after a fixed time limit; see SetDeadline and SetReadDeadline.



因此,如果您不想阻止它(根据评论),那么您可以:
  • 使用SetDeadlineSetReadDeadline设定最后期限。
  • 运行ReadFromUDP在 goroutine 中处理接收到的数据(可能包括将接收到的数据放入 channel )

  • 注意:调用 ReadFromUDP长度为零的缓冲区可能不会阻塞,但这取决于 operating system implementation所以可能不是可以依赖的东西。

    关于go - UDP 永远读取 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60217773/

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