当前,我在服务器端和客户端都使用此代码。客户端是一个android设备。
BufferedOutputStream os = new BufferedOutputStream(socket.getOutputStream(),10000000);
BufferedInputStream sin = new BufferedInputStream(socket.getInputStream(),10000000);
os.write("10000000\n".getBytes());
os.flush();
for (int i =0;i<10000000;i++){
os.write((sampleRead[i]+" ").getBytes());
}
os.flush();
问题是此代码需要大约80秒才能将数据从android客户端传输到服务器,而仅需要8秒钟即可将数据从服务器传输回客户端。双方的代码相同,缓冲区也相同。我也尝试过使用不同的缓冲区大小,但是问题出在这一段
for (int i =0;i<10000000;i++){
os.write((sampleRead[i]+" ").getBytes());
}
在150mbps热点连接上,缓冲花费大部分时间,而实际传输仅花费约6-7秒。可能是什么问题以及如何解决?
答案 0 :(得分:2)
您可以压缩数据传输,这将节省大量内存,并且传输压缩数据流的成本也更低。为此,您需要在客户端实现压缩逻辑并在服务器端实现解压缩逻辑,请参见GZIPInputStream ...并尝试减小缓冲区大小对于移动设备来说是巨大的...
答案 1 :(得分:2)
首先,正如评论者已经指出的那样,使用巨大的缓冲区可能会适得其反。一旦流缓冲区大于网络数据包的大小,应用程序端缓冲就会失去其有效性。 (“大”缓冲区中的数据在进入网络之前,需要先由TCP / IP堆栈拆分成数据包大小的块。)确实,如果应用程序端缓冲区很大,您可能会发现数据在网络实际上处于空闲状态时,卡在缓冲区中的时间很长,等待缓冲区填充...。
(Buffered...
读取器,写入器和流的主要目的是避免传送大量数据的大量系统调用。大约10K以上,缓冲对性能没有太大帮助。)
现在的另一件事是,在许多操作系统环境中,网络吞吐量实际上受到虚拟化和默认网络堆栈调整参数的限制。为了获得更好的吞吐量,您可能需要在操作系统级别进行调整。
最后,如果您的网络路径经过拥塞的网络路径,具有高的端到端延迟或具有受限数据速率的链接,那么无论您如何调整内容,都不太可能获得快速的数据传输。
(压缩可能会有所帮助……如果您可以负担两端的CPU开销……但是某些数据链接已经透明地进行压缩了。)