gpt4 book ai didi

Java 套接字服务器滞后于两个客户端

转载 作者:搜寻专家 更新时间:2023-11-01 03:48:54 25 4
gpt4 key购买 nike

我是 StackOverflow 的新手,哈哈,但我已经依赖这个网站一段时间了。我对我创建的 Java 套接字服务器有疑问。连接(客户端和服务器)后,我的应用程序为该客户端创建一个线程。这是一个 MMORPG 游戏服务器......至少试图成为。对于一名球员,它不会落后那么糟糕。然而,有两个时,它开始显示出一些滞后......

如果我要在其中一个客户端上左右发送垃圾邮件,而与另一个客户端一起正常移动,另一个客户端会感到故障。我希望能得到一些助手,因为我已经花了一个多星期半的时间纠结 =) 是时候寻求帮助了。

代码很简单:

public static void main(String[] args) throws IOException{
serverRooms.put(roomNumber, new Room());

try {
System.out.println("Starting Server...");
serverSocket = new ServerSocket(9595, 20);

System.out.println("Server Started");
while(run){
Socket socket = serverSocket.accept(); // Check if we have a connection, otherwise wait

Player player = new Player(playerCount++, socket, roomNumber);
new Thread(player).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}

一切就这样开始了!在 Player 对象上,它看起来像:

public void run() {
while(playerIsConnected) {
try {
int msgid = input.readUnsignedByte();
messageHandler(this, msgid);

} catch (IOException e) {
System.err.println("Player have signed off");
playerIsConnected = false;
}
}

// If Player leaves, close socket, and end thread
try {
socket.close();
} catch (IOException e) {
System.out.println("We got an error while closing a socket on player " + pid + ".");
}
}

messageHandler 恰好是 Final Static 类中的静态方法。它是一个全局方法,可以被每个线程调用(这会不会是延迟的原因??)

public final class MessageControl {

public static void messageHandler(Player player, int msgid) throws IOException{
DataInputStream input = player.getInputStream();
switch (msgid) {
case 10:
byte hspd = (byte) Math.signum(input.readByte());
byte vspd = (byte) Math.signum(input.readByte());
byte dir = input.readByte();

updatePlayerPosition(player);
byte spd = (byte) (hspd != 0 && vspd != 0 ? player.spd-1 : player.spd);

// Prepare packet and send to clients
ByteBuffer buffer = ByteBuffer.allocate(11);
buffer.put((byte) 10);
buffer.put(shortToByte_U16(player.pid));
buffer.put(shortToByte_U16(player.x));
buffer.put(shortToByte_U16(player.y));
buffer.put((byte)(hspd*spd));
buffer.put((byte)(vspd*spd));
buffer.put((byte)(dir));
sendPacketToAllClients(player, buffer, true);

// Update Player info
player.hspd = (byte) hspd;
player.vspd = (byte) vspd;
player.dir = dir;
player.lastUpdate = System.currentTimeMillis();
break;
}
private static void sendPacketToAllClients(Player player, ByteBuffer buffer, boolean includeMe){
for (Player otherPlayer : player.room.getPlayersInRoom()){
if (otherPlayer.pid != player.pid || includeMe){
sendPacketToClient(otherPlayer, buffer);
}
}
}
}

关于 shortToByte_U16(),我刚刚创建了一个简单的方法,将 shorts 转换为字节(通过字节向客户端发送缓冲数据包)。例如,我有大约 5 个这样的转换,其中包括无符号 u16 的转换

public static byte[] shortToByte_16(int x){
short s = (short) x;
byte[] ret = new byte[2];
ret[0] = (byte)(s & 0xff);
ret[1] = (byte)((s >> 8) & 0xff);
return ret;
}

看看下面的结构,我为什么会落后?

编辑:我认为我通过将 setTcpNoDelay 设置为 true 改进了很多。当我向左/向右发送垃圾邮件时,延迟似乎仍然存在……我屏幕上的其他播放器似乎出现故障。

            Socket socket = serverSocket.accept();      // Check if we have a connection, otherwise wait
socket.setTcpNoDelay(true); // This helped a lot!!!
Player player = new Player(playerCount++, socket, roomNumber);
new Thread(player).start();

据我所见...我的“左/右垃圾邮件”端似乎丢失了服务器发送的数据包。

最佳答案

问题解决了。 =) setTcpNoDelay true 成功了。关于我说我丢失数据包的部分,我实际上没有。这两条消息合并为一条消息。我的程序只读取前几个字节而忽略其余部分。不得不在前面放一个字节来指示消息的大小。一旦到位,我设置了一个 while 循环来读取它,直到它无法再读取为止。 =) 感谢大家帮助我。我的第一篇文章,这是一次很棒的经历。

关于Java 套接字服务器滞后于两个客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34196438/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com