当前位置: 首页 > 面试题库 >

Golang UDP服务器的奇怪行为

西门洛城
2023-03-14
问题内容

我在go中编写了一个简单的UDP服务器。

当我这样做时,go run udp.go它会打印我发送给它的所有包裹。但是,当客户端停止运行时,go run udp.go > out它将停止传递stdoutout文件。

客户端是发送10k请求的简单程序。因此,在文件中,我大约有50%的已发送软件包。当我再次运行客户端时,out文件会再次增长,直到客户端脚本完成。

服务器代码:

package main

import (
  "net"

  "fmt"
)

func main() {
  addr, _ := net.ResolveUDPAddr("udp", ":2000")
  sock, _ := net.ListenUDP("udp", addr)

  i := 0
  for {
    i++
    buf := make([]byte, 1024)
    rlen, _, err := sock.ReadFromUDP(buf)
    if err != nil {
      fmt.Println(err)
    }
    fmt.Println(string(buf[0:rlen]))
    fmt.Println(i)
    //go handlePacket(buf, rlen)
  }
}

这是客户端代码:

package main

import (
  "net"

  "fmt"
)

func main() {

  num := 0
  for i := 0; i < 100; i++ {
    for j := 0; j < 100; j++ {
      num++
      con, _ := net.Dial("udp", "127.0.0.1:2000")
      fmt.Println(num)
      buf := []byte("bla bla bla I am the packet")
      _, err := con.Write(buf)
      if err != nil {
        fmt.Println(err)
      }
    }
  }
}

问题答案:

如您所怀疑,由于UDP的性质,似乎 UDP数据包丢失
。由于UDP是无连接的,因此客户端不关心服务器是否可用或准备接收数据。因此,如果服务器忙于处理,它将无法处理下一个传入的数据报。您可以进行检查netstat -u(其中应包括UDP数据包丢失信息)。我遇到了同样的事情,服务器(接收端)无法跟上发送的数据包的速度。

您可以尝试两种方法(第二种方法适用于您的示例):

调用SetReadBuffer。 确保接收套接字具有足够的缓冲以处理您向其抛出的所有内容。

sock, _ := net.ListenUDP("udp", addr)
sock.SetReadBuffer(1048576)

在go例程中进行所有数据包处理。
尝试通过确保服务器在希望接收时不忙于其他工作来每秒增加数据报。即,将处理工作移至go例程,因此您无需按住ReadFromUDP()。

//Reintroduce your go handlePacket(buf, rlen) with a count param
func handlePacket(buf []byte, rlen int, count int)
        fmt.Println(string(buf[0:rlen]))
        fmt.Println(count)
}

go handlePacket(buf, rlen, i)

最后一种选择:

最后,可能不是您想要的,您 在客户睡个好觉, 这会减慢速度并消除问题。例如

buf := []byte("bla bla bla I am the packet")
time.Sleep(100 * time.Millisecond)
_, err := con.Write(buf)


 类似资料:
  • 如果我有0条消息要接收,操作需要大约30-60秒来获得messageList(它的计数为0)。我需要这个马上归还。 如果我将代码更改为

  • 问题是当从代码(使用回形针的Ruby on Rails)上传图像时,可以正常访问该图像,但是当尝试调整url大小(例如/100x200/photo.png)时,我在浏览器中接收到该图像作为json响应 非常奇怪的是,在错误发生后,当我再次手动上传相同的图像到桶中的任何地方,然后我再次尝试使用原始的调整大小url,而不是导致问题的新上传图像url,它正常工作,我可以调整大小到任何大小! 所以手动上传

  • 我有以下代码来解析一个JSON文件: 要处理以下JSON文件: 如果我执行此代码,我将收到以下错误: 所以我开始一步一步地调试应用程序,看看part processing()中的哪个代码部分抛出了这个异常。令人惊讶的是,那里的所有代码都正常执行:没有抛出异常,也没有返回结果I except。 更让我惊讶的是,当我稍微改变第一种方法的代码时,它可以在不产生异常的情况下工作。 我不知道println方

  • 问题内容: 我在GregorianCalendar类中遇到一个奇怪的行为,我想知道我是否真的做得不好。 仅当初始化日期的月份的实际Maximum大于我将日历设置为的月份时,才追加此值。 这是示例代码: 我知道问题是由于日历初始化日期是31天(可能是5月),与设置为2月(28天)的月份混淆了。修复很容易(只需在设置年和月之前将day_of_month设置为1),但是我想知道这确实是想要的行为。有什么

  • 问题内容: 我正在为一个问题而苦苦挣扎,我不明白为什么它不起作用。如何通过将变量传递并转换为? 为什么在顶部代码段中不起作用,但在行下方的底部代码段中起作用? 唯一的区别似乎是添加了一个额外的变量,该变量也被键入为? 问题答案: 该是一种原始类型,同时是一个普通的Java类。您不能在原始类型上调用方法。但是该方法在上可用,如javadoc中所示 有关这些原始类型的更多信息,请参见此处

  • 问题内容: 为什么的到哪里去了? 问题答案: 删除任何字符,并从字符串的开头和结尾。