当前位置 : 主页 > 网页制作 > HTTP/TCP >

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

来源:互联网 收集:自由互联 发布时间:2021-06-16
使用HTTP而不是普通套接字( Android上的Java)通过Wi-Fi网络从Android设备向Linux服务器发送大型(50-200 MB)文件[文件在SD卡上]是否存在大量开销. 在我目前的原型中,我使用CherryPy-3.2.0来实现我的
使用HTTP而不是普通套接字( Android上的Java)通过Wi-Fi网络从Android设备向Linux服务器发送大型(50-200 MB)文件[文件在SD卡上]是否存在大量开销.

在我目前的原型中,我使用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(); 

}

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

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

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

从spec:

The content type “application/x-www-form-urlencoded” is inefficient for sending
large quantities of binary data or text containing non-ASCII characters. The
content type “multipart/form-data” should be used for submitting forms that
contain files, non-ASCII data, and binary data.

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

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

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

记得:

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

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

网友评论