0

我正在尝试为我正在制作的 Unity3D 游戏制作一个简单的 UDP 套接字服务器,并且我已经让它大部分工作。我可以向它发送消息并阅读消息。但是当我试图将消息发送回客户端时(目前用于测试目的),我得到了一个 BufferOverFlowException。

在发回数据之前,我使用 groovy.json.JsonBuilder 将其转换为 json。数据有一个非常简单的结构:

[数据:“Hello World”]

但无论出于何种原因,JsonBuilder 将其构建为

{ "data": "Hello World\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\..." }

\u0000 会持续一段时间。长到足以让我的 1024 字节长的 ByteBuffer 溢出。

这是负责将数据发送回客户端的类:

import groovy.json.JsonBuilder
import groovy.transform.CompileStatic
import groovyx.gpars.actor.DynamicDispatchActor

import java.nio.ByteBuffer
import java.nio.channels.DatagramChannel

@CompileStatic
class SenderActor extends DynamicDispatchActor{

    //takes message of type [data: Object, receiver: SocketAddress]
    void onMessage(Map message){

        println(message.data) //prints "Hello World"
        def json = new JsonBuilder([data: message.data]).toString()
        println("Sending: $json") //prints '{"data": "Hello World\u0000\u0000..."}'

        def channel = DatagramChannel.open()
        channel.connect(message.receiver as SocketAddress)

        def buffer = ByteBuffer.allocate(1024)
        buffer.clear()
        buffer.put(json.getBytes())
        buffer.flip()

        channel.send(buffer, message.receiver as SocketAddress)
    }
}

这是我得到的堆栈跟踪:

An exception occurred in the Actor thread Actor Thread 2
java.nio.BufferOverflowException
    at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:189)
    at java.nio.ByteBuffer.put(ByteBuffer.java:859)
    at Croquet.Actors.SenderActor.onMessage(SenderActor.groovy:28)
    at Croquet.Actors.SenderActor$onMessage.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at Croquet.Actors.ProcessorActor$onMessage.call(Unknown Source)
    at groovyx.gpars.actor.impl.DDAClosure$_createDDAClosure_closure1.doCall(DDAClosure.groovy:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:292)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
    at groovy.lang.Closure.call(Closure.java:423)
    at groovy.lang.Closure.call(Closure.java:439)
    at groovyx.gpars.actor.AbstractLoopingActor.runEnhancedWithoutRepliesOnMessages(AbstractLoopingActor.java:293)
    at groovyx.gpars.actor.AbstractLoopingActor.access$400(AbstractLoopingActor.java:30)
    at groovyx.gpars.actor.AbstractLoopingActor$1.handleMessage(AbstractLoopingActor.java:93)
    at groovyx.gpars.util.AsyncMessagingCore.run(AsyncMessagingCore.java:132)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

有问题的数据被编码为 UTF-8,如果有帮助的话。

这是负责向服务器发送数据的客户端代码(用 C# 编写):

void sendTestMessage(UdpClient udpClient, UdpState udpState){
        byte[] data = Encoding.UTF8.GetBytes("Hello World");
        udpClient.BeginSend(
            data, 
            data.Length, 
            udpState.e, //IPEndPoint
            result =>{
                messageSent = true;
                Debug.Log(string.Format("Message '{1}' Sent to {0}", udpState.e, Encoding.UTF8.GetString(data)));
                udpClient.EndSend(result);
            }, 
            udpState);
    }
4

1 回答 1

0

我通过改变解决了我的问题

def json = new JsonBuilder([data: message.data]).toString()

def json = new JsonBuilder([data: message.data]).toString().replace("\\u0000", "")

于 2015-09-03T16:11:22.400 回答