[gogf/gf]gudp不能完整接收数据

2024-06-25 310 views
7
我使用的环境:

操作系统:windows 7 GoLang版本:1.12.5 gf版本:v1.10.0

问题描述:

用原生的库写了一个数据报发送程序,在用Gudp库接收数据时,每条数据只能看到64个字节.

发包程序go代码:
package main

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

func main() {
    //循环发送json串到指定端口
    conn, err := net.Dial("udp", ":8801")
    if err != nil {
        panic(err)
    }
    var a,b,c int
    for {

        a, _ = conn.Write([]byte(`{"I_Code":4300770,"F_Open":87.800,"F_Close":89.280,"F_High":89.890,"F_Low":86.700,"F_RefClose":86.800,"F_Hsl":3.562,"F_Qrr":0.701,"I_FromOpen":240,"I_timeNumber":16,"D_vol":1.1433,"D_amount":1.0134,"I_date":190927,"I_time":194904,"I_week":0,"F_ntg":0.000,"I_pznx":3,"I_type":5,"I_1mVol":68}`))
        time.Sleep(400 * time.Millisecond)

        b, _ = conn.Write([]byte(`{"I_Code":3002409,"F_Open":20.440,"F_Close":21.010,"F_High":21.350,"F_Low":19.800,"F_RefClose":20.400,"F_Hsl":4.297,"F_Qrr":0.782,"I_FromOpen":240,"I_timeNumber":16,"D_vol":10.2159,"D_amount":2.1105,"I_date":190927,"I_time":194920,"I_week":0,"F_ntg":0.000,"I_pznx":2,"I_type":5,"I_1mVol":544}`))
        time.Sleep(400 * time.Millisecond)

        c, _ = conn.Write([]byte(`{"I_Code":1000016,"F_Open":2929.320,"F_Close":2929.470,"F_High":2934.330,"F_Low":2916.070,"F_RefClose":2927.880,"F_Hsl":0.000,"F_Qrr":0.880,"I_FromOpen":240,"I_timeNumber":16,"D_vol":2301.4561,"D_amount":324.2235,"I_date":190927,"I_time":194906,"I_week":0,"F_ntg":0.000,"I_pznx":0,"I_type":5,"I_1mVol":108948}`))
        time.Sleep(400 * time.Millisecond)

        fmt.Printf("发送数据字节分别为:a=%d,b=%d,c=%d\n",a,b,c)
    }
}
接收数据的代码:
package main

import (
    "fmt"
    "github.com/gogf/gf"
    "github.com/gogf/gf/net/gudp"
)

func main() {
    gudp.NewServer("127.0.0.1:8801", func(conn *gudp.Conn) {
        fmt.Println(gf.VERSION)
        fmt.Println("UDP server is running...")
        defer conn.Close()
        for {
            if data, _ := conn.Recv(-1); len(data) > 0 {
                fmt.Println(string(data))
            }
        }
    }).Run()
}
我这边接收到的数据:
v1.10.0
UDP server is running...
{"I_Code":4300770,"F_Open":87.800,"F_Close":89.280,"F_High":89.8
{"I_Code":3002409,"F_Open":20.440,"F_Close":21.010,"F_High":21.3
{"I_Code":1000016,"F_Open":2929.320,"F_Close":2929.470,"F_High":
请帮忙看看是哪儿出了问题?

回答

7

1.10好像没有类似gtcp里面的SendPkg和RecvPkg之类的粘包处理工具方法了,你这不完整的原因是,Recv(-1)会取默认buffer长度,64. 估计要么John提供类似方法,要么自己处理包大小之类的.或者自己仿照gtcp写一个.

1

UDP协议天生没有粘包的问题, 不用处理.只管接收完整一条数据报即可.据说最大包长度可达65535字节.但是参考TCP协议MTU长度,至少可以是1460字节.

7

了解,不过打印错误发现这个 wsarecvfrom: A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself ,具体限制在哪没找到.这个错误回导致自动扩容buffer不会生效,所以,好吧,我还是懵逼状态.

7

已经确认是bug了.首先超过默认长度的数据要设置retry,不过jhon设置重试间隔时间的时候多乘了一个单位,导致重试逻辑跳出,无法返回扩容后的buffer.

2

若在明确知道待接收数据的大概长度时,还要每次按64字节来扩容, 貌似有点浪费资源. 看能否考虑下将这个64字节设计成可自定义的配置. @johngcn

7

@TerryLiu 请更新到最新的版本再试试。