我的程序使用 SSL ServerSocket
来等待传入连接和接收数据。
客户端连接到服务器并将一系列 10 字节 block 写入 Socket
的 OutputStream
。在每个 10 字节 block 之后,OutputStream
被 flush()
编辑,因为 block 应该尽快到达服务器(注意:这里使用 WIFI)。
然后服务器读取这些 block 。使用 OpenJDK 7 在 Ubuntu Linux 上运行服务器工作正常。
但是在使用 Suns Java 7 的 Windows 上运行服务器会导致以下问题:
我测量了服务器上接收到的数据 block 之间的时间。我注意到虽然客户端在写入 block 后使用 flush()
,但有时服务器接收/读取数据的时间太晚了。
例如:
接收第一个 block 需要 265 毫秒。接下来的 15 个 block 有 0 毫秒到 16 毫秒的延迟。
之后下一个 block 在 172 毫秒后到达。但接下来的 10 个 block 再次只需要 0 毫秒到 16 毫秒。
所以看起来首先一些字节被 InputStream 接收和缓冲。然后在某个时间点(例如超过 150 毫秒后)InputStream
的read
方法返回一些数据。之后,read
方法会立即(0 毫秒到 16 毫秒)返回一些字节的数据。然后又需要一些时间。
我知道 InputStream
使用缓冲区,而 read
方法会阻塞,直到有新字节可用。但似乎 read
方法没有尽可能快地返回数据。
客户端始终是一个 Android 应用程序。但是由于在 Linux 上运行的服务器不会出现问题( block 之间的平均间隔始终为 20 毫秒),问题一定出在服务器或 JRE 上。
关于如何解决问题的任何想法?我真的需要客户端发送的 block 的“流畅”传输,因为 Android 应用程序上的交互应该在服务器上显示为近乎实时的动画。但是由于延迟了 265 毫秒,这些动画卡住了。
最佳答案
InputStream buffers data
不,它没有。没有任何 InputStream 缓冲,除非您使用 BufferedInputStream。您的发送 由内核中的 TCP Nagle 算法合并。在发送方调用 Socket.setTcpNoDelay(true)。
您应该知道,通过 SSL 发送 10 字节的数据 block 效率极低。 SSL 本身有大约 44 个字节的记录开销,而 TCP 还有 20 个字节,所以你有将近 4 倍的数据爆炸。如果可能,请使用纯文本。
关于java - InputStream 缓冲数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12749237/