我跟着this Youtube tutorial介绍了Kryonet的基础知识。
基本上它是一个Kryonet Hello World,它解释了如何设置基本服务器和客户端,允许客户端将数据包发送到服务器并进行非常基本的通信。
指向source code的链接。 Server和Client都具有相同的Packet类。
我可以让服务器运行,客户端要求IP连接。但是,当我输入IP时,客户端会在连接后终止。
客户端输出:
00:03 INFO: Connecting: /127.0.0.1:54555
00:03 INFO: [kryonet] Connection 1 connected: /127.0.0.1
00:03 INFO: [CLIENT] You have connected.
BUILD SUCCESSFUL (total time: 3 seconds)
服务器命令行日志:
00:00 INFO: [kryonet] Server opened.
00:04 DEBUG: [kryonet] Port 54555/TCP connected to: /127.0.0.1:53217
00:04 DEBUG: [kryo] Write: RegisterTCP
00:04 INFO: [kryonet] Connection 1 connected: /127.0.0.1
00:04 INFO: [SERVER] Someone has connected.
00:04 DEBUG: [kryonet] Connection 1 update: Se ha forzado la interrupcion de una
conexion existente por el host remoto
00:04 INFO: [SERVER] Someone has disconnected.
00:04 INFO: [kryonet] Connection 1 disconnected.
好像系统关闭了TCP连接,但我真的不知道。我必须在Windows或/和路由器中启用某些东西以允许Kryonet的通信吗?
有人能发现问题吗?提前谢谢。
命令行日志中以西班牙语显示的行类似于“远程主机强制中断连接的连接。”
在user1816380建议后编辑:
大多数时候它仍会显示原始错误,但有时您会看到:
00:00 INFO: [kryonet] Server opened.
00:07 DEBUG: [kryonet] Port 54555/TCP connected to: /127.0.0.1:50787
00:07 DEBUG: [kryo] Write: RegisterTCP
00:07 INFO: [kryonet] Connection 1 connected: /127.0.0.1
00:07 INFO: [SERVER] Someone has connected.
00:07 DEBUG: [kryo] Read: Packet0LoginRequest
00:07 DEBUG: [kryonet] Connection 1 received TCP: Packet0LoginRequest
00:07 DEBUG: [kryo] Write: Packet1LoginAnswer
00:07 DEBUG: [kryonet] Connection 1 sent TCP: Packet1LoginAnswer (6)
00:07 DEBUG: [kryonet] Connection 1 update: Se ha forzado la interrupcion de una
conexion existente por el host remoto
00:07 INFO: [SERVER] Someone has disconnected.
00:07 INFO: [kryonet] Connection 1 disconnected.
答案 0 :(得分:6)
为了让您的客户端保持连接,它需要发送和接收KeepAlive数据包。 当你调用client.start(); client.connect(); 客户端线程在后台启动,自动为您处理。
看起来你正在阻止客户端线程执行此操作,因为你使用无限循环来阻止它来处理用户输入(While(true)获取用户输入)。
相反,您应该有一个单独的线程来接受用户输入。 这是实现客户端接收功能的一种方式(可能不是最好的方法):
public void received(Connection c, Object o) {
System.out.println("received something");
if (o instanceof Packet1LoginAnswer){
boolean answer = ((Packet1LoginAnswer) o).accepted;
if (answer) {
System.out.println("Please enter your message for server");
new Thread("Get User Input") {
public void run () {
try {
if (ChatClient.scanner.hasNext()){
Packet2Message mpacket = new Packet2Message();
mpacket.message = ChatClient.scanner.nextLine();
client.sendTCP(mpacket);
System.out.println("Please enter another message");
}
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
}.start();
} else {
System.out.println("Answer is false");
c.close();
}
}
if (o instanceof Packet2Message){
String message = ((Packet2Message) o).message;
Log.info(message);
}
}
我也注意到你使用的是Log.info()。 这仅适用于使用Kryonet的Debug版本。 最好只使用标准输出功能。
答案 1 :(得分:2)
我刚才有同样的问题,我尝试了所有其他答案,但他们没有工作。
原来我在TCP端口1941
和UDP端口1942
上托管服务器
然而,我的客户端连接到具有TCP端口1941
的服务器(忽略UDP端口)。像这样添加UDP端口解决了它:
client.connect(5000, address, 1941, 1942);
答案 2 :(得分:1)
我认为你不是在一个单独的线程中启动客户端。
“从r122开始,客户端更新线程被制作成守护程序线程,导致子进程在完成初始化后立即关闭。”,解决方案是“也许你可以使用它?新线程(客户端).start( );”
所以,举个例子来说,你就是这样开始你的客户
client.start();
而应该使用
new Thread(client).start();
答案 3 :(得分:0)
这个问题和行为可能与使用最新版本的KryoNet 2.20有关。例如,当使用kryonet-2.12时,很可能会解决问题。
因此,尝试使用kryonet-2.12而不是kryonet-2.20,该示例应该有效; - )
答案 4 :(得分:0)
我不确定这是否相关(因为您的源代码链接不再有效)但是...
如果您将服务器配置为TCP 和 UDP,然后让客户端 通过TCP连接,则可能会出现您所描述的问题。
如果您想要利用主机发现但之后只需要TCP连接,那么建议您"run a separate server for UDP discovery"。