我只是在线程中使用普通的 DataInputStream 和 DataOutputStream 来接收、发送(在服务器上接受)来制作游戏,但它真的很慢。 >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);
对于输入(这个在服务器中)我使用:
(dis 是 DataInputStream,它在一个 for 循环中所以 i 代表每个玩家)
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();
所以它真的很慢,但我不知道为什么:( 请帮忙?
编辑:每个操作(发送、接受、接收)都有自己的守护线程。
最佳答案
重复创建 DataOutputStream
和 DataInputStream
实例对性能不利。
但是,我怀疑一个更重要的性能问题是您在没有任何 Java 端缓冲的情况下进行读写。这意味着每次读/写调用都会进行一次(也可能多次)系统调用来读取数据。系统调用比普通的 Java 方法调用慢几个数量级。
您需要将 Socket 输入流包装在 BufferedInputStream
中,将输出流包装在 BufferedOutputStream
中,然后将它们包装在数据流中。 (请注意,执行此操作时,在每条消息或一系列消息末尾刷新
DataOutputStream
变得更加重要。
Do I write a few info, and then flush after every each write?
就像我上面说的,您在每条消息或每条消息序列的末尾刷新。假设缓冲区中有要刷新的数据,缓冲输出流上的每次刷新都会导致系统调用。如果您在每次写入时都进行刷新,那么您(可能)正在执行不必要的系统调用。
由您决定协议(protocol)的消息边界应该在哪里。这完全取决于您发送/接收的数据的详细信息及其处理方式。
关于Java:套接字 - DataStream 真的很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10461302/