HTTP Vs Vanilla套接字,用于通过单跳Wi-Fi网络从Android设备上传大型二进制文件(50-200 MB)

Sou*_*nta 3 sockets performance android http cherrypy

使用HTTP而不是普通套接字(Android上的Java)通过Wi-Fi网络将大型(50-200 MB)文件[文件在SD卡上]从Android设备发送到Linux服务器是否存在大量开销.

在我目前的原型中,我使用CherryPy-3.2.0来实现我的HTTP服务器.我在Nexus上运行Android 2.3.3作为我的客户端.

目前它需要约100秒**(在较慢的网络18 Mbps*上)和约50秒(在更快的54 Mbps*上)Wi-Fi网络上传50 MB二进制文件.

注意:
*WifiInfo.getLinkSpeed()用来衡量网络链接速度

**这是之前和之后的时差HTTPClient.execute(postRequest)

关于其他昂贵的操作的任何其他想法可能在网络之外的总时间中占很大比例并且如何减少这个时间将是值得赞赏的.

谢谢.

编辑 - Android上的HTTP发布代码

private void doHttpPost(String fileName) throws Exception{

    HttpParams httpParameters = new BasicHttpParams();

    // Set the timeout in milliseconds until a connection is established.
    int timeoutConnection = 9000000;
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
    // Set the default socket timeout (SO_TIMEOUT) 
    // in milliseconds which is the timeout for waiting for data.
    int timeoutSocket = 9000000;
    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

    HttpClient client = new DefaultHttpClient(httpParameters);

    client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109);

    HttpPost postRequest = new HttpPost();
    postRequest.setURI(new URI("http://192.168.1.107:9999/upload/"));

    MultipartEntity multiPartEntity = new MultipartEntity();
    multiPartEntity.addPart("myFile", new FileBody(new File(fileName)));
    postRequest.setEntity(multiPartEntity);

    long before = TrafficStats.getTotalTxBytes();
    long start = System.currentTimeMillis();
    HttpResponse response = client.execute(postRequest);
    long end = System.currentTimeMillis(); 
    long after = TrafficStats.getTotalTxBytes();

    Log.d(LOG_TAG, "HTTP Post Execution took " + (end - start) + " ms.");


    if( before != TrafficStats.UNSUPPORTED && after != TrafficStats.UNSUPPORTED)
        Log.d(LOG_TAG, (after-before) + " bytes transmitted to the server");
    else
        Log.d(LOG_TAG, "This device doesnot support Network Traffic Stats");

    HttpEntity responseEntity = response.getEntity();


    if (responseEntity != null) {
        responseEntity.consumeContent();
        Log.d(LOG_TAG, "HTTP Post Response " + response.getEntity().getContent().toString() );
    }

    client.getConnectionManager().shutdown(); 

}
Run Code Online (Sandbox Code Playgroud)

编辑2:根据此工具报告的结果,看起来SD卡读取速度不是问题.所以它可能是HttpClient库或其他东西. 在此输入图像描述 在此输入图像描述

ska*_*bes 9

HTTP连接的开销来自它与数据一起发送的标头(基本上是一个常量).因此,您发送的数据越多,标题"伤害您"的次数就越少.但是,要考虑的更重要的方面是编码.

例如,如果要发送非ASCII数据,与mime类型配对,application/x-www-form-urlencoded则存在爆炸输入大小的风险,因为必须转义非ASCII字符.

规格:

内容类型"application/x-www-form-urlencoded"对于发送大量二进制数据或包含非ASCII字符的文本效率低下.内容类型"multipart/form-data"应该用于提交包含文件,非ASCII数据和二进制数据的表单.

替代方案multipart/form-data对二进制数据有效.因此,请确保您的应用程序使用此MIME类型(您甚至可以在服务器日志上检查此类型).

另一种可以大大减少上传时间的方法是压缩.如果要上传尚未压缩的数据(大多数图像和视频格式已经压缩),请尝试在上传中添加gzip压缩. 另一篇文章显示了在android中设置它的细节.

如果您的数据是特定格式(例如图像),您可以查看适用于您的数据类型的无损压缩算法(png用于图像,FLAC用于音频等).压缩始终以CPU(电池)为代价,因此请记住这一点.

记得:

在知道瓶颈之前不要优化.也许你的服务器连接速度很慢,也许你无法从android文件系统中快速读取数据到网络.运行一些测试,看看哪些有效.

如果是我,我不会实施直接的tcp方法.我的2美分,祝你好运!

  • 我打赌你没有得到任何压缩.首先尝试压缩然后加密.我敢打赌,如果你这样做,你会发现尺寸要小得多. (3认同)