Java Socket Server滞后于两个客户端
发布时间:2020-12-15 02:11:58 所属栏目:Java 来源:网络整理
导读:我是StackOverflow的新手lol,但我一直依赖这个网站.我有一个关于我创建的 Java套接字服务器的问题.在连接(客户端和服务器)时,我的应用程序为该客户端创建一个线程.这是一款MMORPG游戏服务器……至少是尝试过.有一个玩家,它不会落后那么糟糕.然而,有两个,它开
我是StackOverflow的新手lol,但我一直依赖这个网站.我有一个关于我创建的
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(),我刚刚创建了一个简单的方法,将锥形短路到字节(通过字节向客户端发送缓冲包).例如,我有大约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++,roomNumber); new Thread(player).start(); 从我所看到的……我的“垃圾邮件左/右”结束似乎缺少服务器发送的数据包. 解决方法
问题解决了. =)setTcpNoDelay true做了伎俩.关于我说我丢失数据包的部分,我实际上没有.这两条消息合并在一起作为一条消息传入.我的程序只读取前几个字节而忽略了其余的字节.不得不在前面放一个字节来表示消息的大小.一旦到位,我设置了一个while循环来读取它直到它不能再读取. =)感谢大家帮助我.我的第一篇文章,这是一次盛大的经历.
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- Java SpringMVC实现PC端网页微信扫码支付(完整版)
- jpa – 必须在ConnectionDriverName属性“如何解决它?”中
- java基础语法
- 使用Java https错误上传到Imgur v3
- java实现二维码生成的几个方法(推荐)
- 即使在简单的POJO Java类中实现java.io.Serializable也是最
- java – 不能在Linkedin上使用linkedin-j发布任何内容
- 谈谈我对Spring Bean 生命周期的理解
- spring boot使用i18n时properties文件中文乱码问题的解决方
- Compiling JSPs Using the Command-Line Compiler---官方