go - 本地主机 UDP 客户端未从 UDP 代理接收数据包

标签 go udp minecraft datagram raknet

关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。












想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。

3年前关闭。




Improve this question




我有一个代理,它在 Minecraft(Windows 10 版)客户端和服务器之间运行,协议(protocol)是 UDP。客户端广播一个未连接的 ping,然后服务器回复一个未连接的 pong,一切正常。问题是当服务器将数据包发送到我的代理时,我的代理将其发送给客户端,但由于某种原因,在那部分发生了一些事情;要么我的代理没有发送数据包,要么客户端没有收到数据包,但很可能是第二种选择。

编辑:我让未连接的 ping 和 pongs 正常工作,现在服务器在服务器列表上显示在线,现在问题主要是打开的连接请求/回复。我如何让 pings 和 pongs 工作是我重新编码缓冲区并发送它们而不是原始发送它们。

在这里你可以从wireshark看到,我的世界客户端发送了一个未连接的ping代理:

NO. Time.       Source.     Dest.       Proto.  Len. Packet
417 10.452413   10.0.0.248  10.0.0.255  RakNet  75   Unconnected Ping (client -> proxy)
430 10.457000   10.0.0.248  x.x.x.x     RakNet  610  Unconnected Ping (proxy -> server)
431 10.587214   x.x.x.x     10.0.0.248  RakNet  212  Unconnected Pong (server -> proxy -> client)

现在代理收到未连接的乒乓球,将其发送给客户端,而客户端没有收到,我可以确认这一点,因为在游戏中服务器显示离线并且不显示任何数据:

Localhost Server Screenshot

在我的代码中,我首先在端口 19132 上绑定(bind)代理并设置我要与之通信的服务器地址:
var config = NewConfig()
var proxy = Proxy{}

var err error

proxy.UDPConn, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP(config.BindAddr), Port: config.BindPort})

if err != nil {
    Panic(err.Error())
    os.Exit(1)
}

Info("Starting proxy on " + config.BindAddr + ":" + strconv.Itoa(config.BindPort))

addrs, err := net.LookupHost(config.ServerAddr)

if err != nil {
    Panic(err.Error())
    os.Exit(1)
}

conn := NewConnection(&proxy)
conn.server.SetAddress(net.UDPAddr{IP: net.ParseIP(addrs[0]), Port: config.ServerPort})

conn.HandleIncomingPackets()

现在我的代理开始自动接收和发送数据包。
for true {
    buffer := make([]byte, 2048)
    _, addr, err := conn.proxy.UDPConn.ReadFromUDP(buffer)

    if err != nil {
        Alert(err.Error())
        continue
    }

    MessageId := buffer[0]

    Debug("Message Id : " + strconv.Itoa(int(MessageId))) // this is the packet id

    if conn.client.IsConnected() { // client is connected
        if conn.IsServer(*addr) {
            conn.pkHandler.HandleIncomingPacket(buffer, conn.client) // if server send to client
        }else{
            conn.pkHandler.HandleIncomingPacket(buffer, conn.server) // if client send to server
        }
    } else {
        switch MessageId {
        case byte(IdUnconnectedPingOpenConnection):
            conn.handleUnconnectedPing(*addr, buffer) // send this server
            break
        case byte(IdUnconnectedPongOpenConnection):
            conn.handleUnconnectedPong(*addr, buffer) // parse server data and send to client
            break
        case byte(IdOpenConnectionRequest1):
            conn.handleConnectionRequest1(*addr, buffer) // connect client and send to server
            break
        //case byte(IdOpenConnectionReply1):
        //  conn.handleConnectionReply1(*addr, buffer)
        //  break
        }
    }
}

这是消息 ID 日志:
[2018-06-10 13:52:12][Log/DEBUG]: Message Id : 1
[2018-06-10 13:52:12][Log/INFO]: Received unconnected ping from client address: 10.0.0.248
[2018-06-10 13:52:12][Log/DEBUG]: Message Id : 28
[2018-06-10 13:52:12][Log/INFO]: Received unconnected pong from server address: x.x.x.x
[2018-06-10 13:52:13][Log/DEBUG]: Message Id : 1
[2018-06-10 13:52:13][Log/INFO]: Received unconnected ping from client address: 10.0.0.248
[2018-06-10 13:52:13][Log/DEBUG]: Message Id : 28
[2018-06-10 13:52:13][Log/INFO]: Received unconnected pong from server address: x.x.x.x

我确认客户端没有收到数据包的另一种方法是,当我在游戏中单击服务器列表中的服务器时,客户端发送 open connection request 1 (5)服务器回复 open connection reply 1 (6) ,客户端应该收到此信息并继续 open connection request 2 (7)然后最后服务器回复 open connection reply 2 (8) ,但客户端从不发送 open connection request 2 (7) ,因为它从来没有得到 open connection reply 1 (6)来自代理,因此超时并断开连接,这是一个日志显示:
[2018-06-10 11:07:46][Log/DEBUG]: Message Id : 5
[5 0 255 255 0 254 254 254 254 253 253 253 253 18 52 86 120 8]
[2018-06-10 11:07:47][Log/DEBUG]: Message Id : 6
[6 0 255 255 0 254 254 254 254 253 253 253 253 18 52 86 120 36 149 162 237 197 55 226 161 0 8 28]
[2018-06-10 11:07:47][Log/DEBUG]: Message Id : 5
[5 0 255 255 0 254 254 254 254 253 253 253 253 18 52 86 120 8]
[2018-06-10 11:07:47][Log/DEBUG]: Message Id : 6
[6 0 255 255 0 254 254 254 254 253 253 253 253 18 52 86 120 36 149 162 237 197 55 226 161 0 8 28]
[2018-06-10 11:07:47][Log/DEBUG]: Message Id : 1
[1 0 0 0 0 3 3 91 191 0 255 255 0 254 254 254 254 253 253 253 253 18 52 86 120 191 216 14 215 31 123 8 249]

最佳答案

经过如此多的调试和测试,我想我只需要继续发送数据报缓冲区,如果它来自服务器,则将其发送到客户端,反之亦然。如果我取消发送数据包,我需要发送一个 ACK​​。就这么简单。

关于go - 本地主机 UDP 客户端未从 UDP 代理接收数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50787346/

相关文章:

sorting - 如何使用多个排序参数对结构进行排序?

node.js - 如何在 Nodejs 中通过 dgram 发送 UDP 数据包?

c++ - 从命令行 Python/C++ 启动 Minecraft

windows - 确保 UDP 中的数据包顺序

java - 我想在玩家重生时传送他,但它不起作用,玩家不会被传送

c# - 标准输入未重定向 C#

go - Go包命名约定背后的想法是什么?

go - 在 sync.Map 中是否有必要使用 Load 后跟 LoadOrStore 来获取复杂值

go - 如何将 Go 结构转换为 C 结构?

linux - UDP套接字是否有可能接收ARP消息