2013-02-27 36 views
1

我使用Kryonet和Slick2d来制作java游戏。Slick2D KryoNet Applet

作为小我碰到下面的错误运行时,但是作为一个Java应用程序运行时,它工作正常:

00:00 INFO: [kryonet] Server opened. 
00:04 DEBUG: [kryonet] Port 9991/TCP connected to: /(ip):55801 
00:04 DEBUG: [kryo] Write: RegisterTCP 
00:04 INFO: [kryonet] Connection 1 connected: /(ip) 
00:04 INFO: [SERVER] Someone has connected. 
00:04 ERROR: [kryonet] Error reading TCP from connection: Connection 1 
com.esotericsoftware.kryonet.KryoNetException: Error during deserialization. 
    at com.esotericsoftware.kryonet.TcpConnection.readObject(TcpConnection.java:141) 

    at com.esotericsoftware.kryonet.Server.update(Server.java:192) 
    at com.esotericsoftware.kryonet.Server.run(Server.java:350) 
    at java.lang.Thread.run(Unknown Source) 
Caused by: com.esotericsoftware.kryo.KryoException: Buffer underflow. 
    at com.esotericsoftware.kryo.io.Input.require(Input.java:162) 
    at com.esotericsoftware.kryo.io.Input.readLong(Input.java:621) 
    at com.esotericsoftware.kryo.io.Input.readDouble(Input.java:745) 
    at com.esotericsoftware.kryo.serializers.DefaultSerializers$DoubleSerializer.read(DefaultSerializers.java:141) 
    at com.esotericsoftware.kryo.serializers.DefaultSerializers$DoubleSerializer.read(DefaultSerializers.java:131) 
    at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:735) 
    at com.esotericsoftware.kryonet.KryoSerialization.read(KryoSerialization.java:57) 
    at com.esotericsoftware.kryonet.TcpConnection.readObject(TcpConnection.java:139) 
    ... 3 more 
00:04 INFO: [SERVER] Someone has disconnected. 
00:04 INFO: [kryonet] Connection 1 disconnected. 

服务器作为一个HTML文件中运行的JAR和客户端小程序在本地运行本地运行,它运行xampp作为Web服务器。

我试过不同的序列化程序,缓冲区大小和发送只是单个字符串/布尔等,它似乎并不喜欢任何东西。 客户端连接到服务器很好,但是当发送任何数据包时,无论发送什么数据包,我都会收到上述错误。

任何帮助/建议将非常感激 - 我一直在这一难以置信! 谢谢

回答

0

我相信我有同样的问题或至少类似的问题。我正在使用Kryonet作为服务器和客户端。客户端是一个小程序,当我通过Eclipse的Applet Viewer运行它时,它工作正常。当我运行它通过Web服务器时,我得到类似的错误。客户端和服务器连接,服务器接收客户端的数据包,但客户端在尝试任何反序列化时都会给出错误。我发现applet的权限是责任。如果您更改Applet查看器的权限(如果您使用的是Eclipse)与网页的权限相同,则会出现相同的错误。优点是你可以调试问题。要更改Eclipse的权限: 转到您的项目文件夹\ bin \并打开“java.policy.applet”。在里面你应该:

grant { 
    permission java.security.AllPermission; 
}; 

修改成:

grant { 
    permission java.io.FilePermission "<<ALL FILES>>", "read, write, execute, delete"; 
    permission java.net.SocketPermission "*", "accept, connect, listen, resolve"; 
    permission java.util.PropertyPermission "*", "read, write"; 
    permission java.lang.RuntimePermission "*"; 
    permission java.awt.AWTPermission "showWindowWithoutWarningBanner"; 
}; 

有了这个改变我对Applet查看相同的行为与嵌入的小程序。这不是一个完整的解决方案,但可以帮助找出问题的原因。

更新: 我发现我的情况是什么问题。问题出在FieldSerializer和其他使用它的序列化程序中。当一个类被注册时,FieldSerializer会遍历它的字段并设置它们全部是可访问的。该操作对于小程序是不允许的。结果是错误的注册和序列化/反序列化。我找到了2个解决方法:

1)使用另一个序列化程序。默认的是一个FieldSerializer并且可以使用

public void setDefaultSerializer (Class<? extends Serializer> serializer) 

另一个选择是设置串行器登记每个类时被改变。不要使用基于FieldSerializer的序列化程序。

2)尝试修复FieldSerializer。我所做的并不完全正确,但是对我来说很有用。如果设置可访问性导致异常,我们将使FieldSerializer继续注册。我们需要做的另一件事是将我们注册的类的所有字段设置为公开。要更改FieldSerializer,您需要Kryo源。转到FieldSerializer.java,编译rebuildCachedFields()。你会在那里找到下面的代码:

if (!field.isAccessible()) { 
     if (!setFieldsAsAccessible) continue; 
     try { 
      field.setAccessible(true); 
     } catch (AccessControlException ex) { 
      continue; 
     } 
    } 

您需要更改到:

if (!field.isAccessible()) { 
     if (setFieldsAsAccessible) 
     try { 
      field.setAccessible(true); 
     } catch (AccessControlException ex) { 
     } 
    } 

需要改变是所有注册类来只有公共领域的另一件事情。

0

我有类似的问题,在gradle构建。可能你只需要增加内存(堆或PermSize)为小程序JVM