我在线程中使用普通的DataInputStream和DataOutputStream进行接收,发送(使用服务器上的accept)来制作游戏,但它确实很慢.> 5秒滞后.
这是我如何制作它(大部分看起来像这样):
(dos是DataOutputStream)
dos = new DataOutputStream(socket.getOutputStream());
dos.writeFloat(dp.x);
dos = new DataOutputStream(socket.getOutputStream());
dos.writeFloat(dp.y);
dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(dp.username);
Run Code Online (Sandbox Code Playgroud)
对于输入(这个在服务器中)我使用:
(dis是DataInputStream,它在for循环中,所以我是每个玩家)
dis = new DataInputStream(list_sockets.get(i).getInputStream());
x = dis.readFloat();
dis = new DataInputStream(list_sockets.get(i).getInputStream());
y = dis.readFloat();
dis = new DataInputStream(list_sockets.get(i).getInputStream());
username = dis.readUTF();
Run Code Online (Sandbox Code Playgroud)
所以它真的很慢,但我不知道为什么:(请帮帮忙?
编辑:每个操作(发送,接受,接收)都有自己的守护程序线程.
反复创建DataOutputStream和DataInputStream实例不利于性能.
但是,我怀疑一个更重要的性能问题是你在没有任何Java端缓冲的情况下进行读写.这意味着每次读/写调用都会使一个(可能很多)系统调用来读取数据.系统调用比普通的Java方法调用慢几个数量级.
您需要将Socket输入流包含在a BufferedInputStream和输出流中BufferedOutputStream,然后将它们包装在数据流中.(请注意,当你做到这一点,就变成你更重要flush的DataOutputStream,在每一个消息,或者一系列消息的结尾.
我是否写了一些信息,然后在每次写入后刷新?
就像我上面说的那样,你会在每条消息或每个消息序列的末尾刷新.假设缓冲区中有数据要刷新,缓冲输出流上的每次刷新都将导致系统调用.如果你在每次写入时都刷新,那么(可能)会进行不必要的系统调用.
由您决定协议的消息边界应该在哪里.它完全取决于您发送/接收的数据的详细信息以及处理方式.