2012-10-05 137 views
0

我的程序使用SSL ServerSocket来等待传入连接和接收数据。 客户端连接到服务器,并向SocketOutputStream写入一个10字节块的序列。在每个10字节块后OutputStreamflush() ed,因为块应该尽快到达服务器(注意:此处使用WIFI)。InputStream缓冲区数据

然后这些块被服务器读取。使用OpenJDK 7在Ubuntu Linux上运行服务器可以正常工作。

但在Windows上使用太阳Java 7运行服务器导致以下问题:
我测量了接收到的块之间的服务器上的时间。我注意到尽管客户端在写入数据块后使用flush(),但数据有时候太晚被服务器接收/读取。

例如:
接收第一个块需要265ms。接下来的15个块有0ms到16ms的延迟。
之后,下一个块在172ms后到达。但是下面的10个块再次只需要0ms到16ms。

所以看起来好像有些字节是由InputStream接收和缓冲的。然后在某个时间点(例如,超过150ms之后),InputStreamread-方法返回一些数据。之后,read-方法立即返回一些字节的数据(0ms到16ms)。然后它又需要一些时间。
我知道一个InputStream使用缓冲区和read - 方法块,直到一个新的字节可用。但似乎read-方法不会尽可能快地返回数据。

客户端始终是Android应用程序。但是由于在Linux上运行的服务器不会发生问题(总是在块之间平均20毫秒),所以问题必须是服务器或JRE。

关于如何解决问题的任何想法?我真的需要客户端发送的块的“流动”传输,因为Android应用上的交互应该以接近实时的动画形式显示在服务器上。但延迟265毫秒这些动画卡住了。

回答

2

的InputStream缓冲区数据

不,它不需要。除非使用BufferedInputStream,否则没有任何InputStream缓冲。您的发送的正由内核中的TCP Nagle算法合并。在发件人处调用Socket.setTcpNoDelay(true)。

您应该知道,通过SSL发送10字节的块是非常低效的。 SSL本身的记录开销约为44字节,而TCP又是20字节,所以你的数据爆炸将近4倍。如果可能的话,请使用明文。

+0

好吧,我的意思是,数据被缓冲“某处”...不一定在InputStream中。 :-)在服务器和客户端上使用'Socket.setTcpNoDelay(true)'解决了这个问题。现在两块之间的时间在大多数情况下只能达到16ms。谢谢 – Biggie

2

为什么你认为这个问题是InputStream读取方法?你是否设置了包嗅探器,实际上是手表的网络流量? Java没有做缓冲,网络堆栈是。通过调整某些套接字设置,您可能会或可能无法影响该功能。