【问题标题】:Much time taken in data read from socket从套接字读取数据花费了很多时间
【发布时间】:2012-06-22 12:50:58
【问题描述】:

我正在使用套接字从一部 Android 手机和 PC 传输数据,我正在使用 DataInputStream

但是数据传输需要很长时间,传输一个 4 MB 的文件大约需要 10 分钟。

有人能提出更好的方法吗?

我对代码进行了一些更改,现在读取大约 1 Mb 的数据需要 15 秒。我想提高它的性能。 我的代码是:

InputStream is= socket.getInputStream();
DataInputStream inChannel= new DataInputStream(new BufferedInputStream(in));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int oneByte;
while ((oneByte = inChannel.read()) != -1) {
        if (oneByte == 0) {
            break;
        }        
        baos.write(oneByte);
        byteCount++;
    }
byte[] inData = baos.toByteArray();
baos.close();

【问题讨论】:

  • 你是如何连接PC和设备的?
  • 屏幕开启比关闭明显快吗?
  • 有很多方法可以降低套接字的效率。显示您的代码。

标签: android sockets data-transfer


【解决方案1】:

你确定你没有在它们之间发送空包或包做其他事情吗?如果您在数据包未到达其目的地的情况下使用 TCP(在路由器或其中一个设备上的连接之间的某处,缓冲区被其他数据包填满),则必须重新发送数据包。这可能是因为您的设置。鉴于您提供给我们的信息很少,我可以给出以下建议:

看看更高级的类型,我假设你没有使用这些类型:

一个发送一个接收线程;发送线程将您放入队列的数据包推出:


|P| - 数据包保存在程序的 Que 部分中

发送线程

接收 -> |磷 |磷 |磷| P -> 应用程序/程序双端队列和分析数据


因为您的发送和接收队列系统相互配合,它们会不断缓冲接收和发送的数据包。您的设置似乎正在发生的事情(据我所知)是您有一个循环来获取最新的数据包并分析它们。这意味着硬件(您的网络硬件的一部分)缓冲区充满了您的程序正在执行其他操作的数据包,并且当您的程序开始收集它们时,其中一些已经丢失。这会导致一方去“我没有得到那些数据包,再次发送它们”,换句话说,你重新发送你应该吸进一个等待出队和分析的队列的数据包。无论程序以多快的速度返回以获取该数据并对其进行处理,队列都会增长(当然,您被限制在 RAM 中)。这样你就可以确保你拥有你应该接收的数据包,而不是依靠你的网卡/接收器为你保留它们,可能会溢出它的缓冲区。


另一种方法是做一个握手系统,其中一个程序等待直到最后一个数据包被传输、接收,而另一端则说“酷,给我下一个”。这会减慢您的下载/上传速度,但比从一个缓冲区末端落下的数据包快一点(每个节点,例如您的路由器都会缓冲您的数据包,以防进入的数据包超过它可以处理的数量)循环)在网络中。


如果可以的话,您应该在一端或两端使用状态机。当您的应用程序正在下载文件时,将其锁定为接收状态,这样它就不会尝试同时发送/接收其他内容。下载完成后,切换到任何其他状态(例如,打开文件状态)。如果你对状态机不太了解,我建议你看看维基百科的文章:

http://en.wikipedia.org/wiki/Finite-state_machine

【讨论】:

  • 这大部分是不正确的。当接收方的接收缓冲区没有空间时,TCP 停止发送数据。
  • 如果数据包仍在传输到缓冲区并且没有空间,则数据包将落在缓冲区的末尾。发送/接收将停止,但这并不能完全解决问题。任何事情都可能发生缓冲区溢出,包括您从中发送的应用程序和许多其他应用程序。这可能发生在网络路由中的任何点,有时没有路由环绕。一旦缓冲区打开,另一端开始再次发送,但是同样的问题会立即出现,因为它再次填满并且传输中的数据包无法排队进入硬件缓冲区......再次
猜你喜欢
  • 2017-05-10
  • 2015-08-02
  • 2023-01-31
  • 1970-01-01
  • 2011-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-31
相关资源
最近更新 更多