Slick2D KryoNet Applet
我使用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服务器。
我试过不同的序列化程序,缓冲区大小和发送只是单个字符串/布尔等,它似乎并不喜欢任何东西。 客户端连接到服务器很好,但是当发送任何数据包时,无论发送什么数据包,我都会收到上述错误。
任何帮助/建议将非常感激 - 我一直在这一难以置信! 谢谢
我相信我有同样的问题或至少类似的问题。我正在使用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) {
}
}
需要改变是所有注册类来只有公共领域的另一件事情。
我有类似的问题,在gradle构建。可能你只需要增加内存(堆或PermSize)为小程序JVM