我正在使用Kryonet和Slick2d来制作一个java游戏。
当作为java应用程序运行时,它工作得很好,但是当作为applet运行时,我得到以下错误:
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.服务器在本地作为可运行的jar运行,客户机applet也在本地作为HTML文件运行,它运行xampp以充当web服务器。
我尝试过不同的序列化程序、缓冲区大小和只发送单个字符串/布尔值等,但它似乎什么都不喜欢。客户端可以很好地连接到服务器,但是当涉及到发送任何数据包时,无论发送什么数据包,我都会收到上面的错误。
任何帮助/建议都会非常感谢--我已经被这个问题困扰了一段时间了!谢谢
发布于 2013-03-09 01:18:46
我相信我也有同样的问题,或者至少是类似的问题。我使用Kryonet作为服务器和客户端。客户机是一个applet,当我通过Eclipse的Applet查看器运行它时,它工作得很好。当我通过web服务器运行它时,我得到了类似的错误。客户端和服务器连接,服务器接收客户端的数据包,但是客户端在尝试任何反序列化时都会给出一个错误。我发现是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查看器的行为与对嵌入式Applet的行为相同。这不是一个完整的解决方案,但可以帮助找到问题的原因。
更新:我已经找到了我的问题所在。问题出在FieldSerializer和使用它的其他序列化程序中。当注册一个类时,FieldSerializer遍历它的字段,并将所有字段都设置为可访问。小程序不允许执行此操作。结果是错误的注册和序列化/反序列化。我找到了两个变通方法:
1)使用另一个序列化程序。缺省值是FieldSerializer,可以使用以下命令进行更改
public void setDefaultSerializer (Class<? extends Serializer> serializer)另一种选择是在注册每个类时设置序列化程序。不要使用基于FieldSerializer的序列化程序。
2)尝试修复FieldSerializer。我所做的并不完全正确,但它在我的情况下是有效的。如果可访问性设置导致异常,我们将使FieldSerializer继续注册。我们需要做的另一件事是将我们注册的类的所有字段都设置为public。要更改FieldSerializer,您需要Kryo源代码。转到FieldSerializer.java,mething 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) {
}
}另一件需要更改的事情是所有注册的类都只有公共字段。
发布于 2013-03-07 20:08:36
我在gradle build中也有类似的问题。您可能只需要为applet JVM增加内存(堆或PermSize
https://stackoverflow.com/questions/15104769
复制相似问题