利用多线程传输原理实现的网络媒体传输加速(附实验代码)

本文提及的的多线程传输指多通道传输。

原理:

把一些多线程的下载技术(例如flashget、网络蚂蚁所用到的),改进为一种数据缓冲技术,应用在文件、媒体等数据传输上。HTTP支持通过Range域来指定开始传输一个资源数据的起始位置。

实验测试:

在宿舍用CMCC的WLAN从www.xiaoxia.org下载一个13MB的文件,
单线程传输平均速度:14kB/s
8个线程传输平均速度:134kB/s

测试发现8个线程的平均传输速度比1个线程的平均传输速度要快,这是为什么呢?

继续测试发现,单个线程传输的时候,速度可能会慢慢减小,所以最后只剩下可怜的14kB/s的平均速度了。而在我实现的网络加速程序里,每个连接的生命时长大概只有10几秒钟,所以它们的速度可以保持很好。


上图的示例是播放一个youku上的高清视频。原来单个连接速度为55kB/s,看高清视频有时候会卡一下。开启网络加速后,使用8个连接同时传输数据,最终平均速度为386kB/s,其中包含了创建连接等待响应的时间,以及一开始计算速度,估计数据缓冲块大小的时间在内。而实际当8个连接同时传输的时候,瞬时速度超过了400kB/s。

但是,实现起来跟多线程下载工具实现在细节上有所不同。因为你需要支持网络流媒体的实时播放,所以你至少需要使用一个缓冲池来存放多线程下载的数据。流媒体是顺序播放的,所以传输位置必须是顺序的,而不能够随机定位一个连接传输数据的位置。

例如下图所示,在缓冲到资源数据的任何一个位置(例如末尾的时候),必须保证前面的数据已经全部获取。

总结

这种通过创建多路连接来突破传输速度而实现的网络加速方法,不需要借助额外的网络服务器,实现起来也很简单,只需要在客户端或者浏览器上进行改进。例如,可以开发一个桌面代理软件来实现本地代理加速,也可以开发一个浏览器插件,又或者可以修改一个Chrome或者Mozzila浏览器内核,发布一个自己的高速浏览器!

注意,此方法不能突破用户网络带宽的限制。

附件

本文所用加速工具源代码及Win32可执行文件下载:
httpspeeder_110402

包含文件:

│  httpSpeeder.exe
│  pthreadGC2.dll
│  readme.txt
│
└─src
        config.cpp
        config.h
        contentbuffer.cpp
        contentbuffer.h
        cppthread.cpp
        cppthread.h
        filelog.cpp
        filelog.h
        httpconnection.cpp
        httpconnection.h
        httpmessage.cpp
        httpmessage.h
        httprequest.cpp
        httprequest.h
        httpresponse.cpp
        httpresponse.h
        httpserver.cpp
        httpserver.h
        httpshrimp.cpp
        httpshrimp.h
        httpsocket.cpp
        httpsocket.h
        httpSpeeder.mk
        httpSpeeder.project
        main.cpp

 

另外,补充一下,用电信专线下载同样大小的文件,
单线程:

8线程:

这下子又没有8倍提速是因为受到xiaoxia.org的服务器输出带宽的限制,不能再提高了!

利用多线程传输原理实现的网络媒体传输加速(附实验代码)》有47个想法

    1. Xiaoxia 文章作者

      附带的工具,我目前还没时间完善。
      例如在跳选youku网上的视频的时候,断点传输会失败。
      也没有对不支持断点续传的网站服务器进行处理。

      回复
  1. soap

    晕一下,测试的时候打开了一个糗百的页面然后刷新一下小虾的博客变成月球了. . .我心里一惊~

    回复
    1. Xiaoxia 文章作者

      你好,这个版本还不稳定,有很多问题!等到稳定的时候,我会多个平台一起发布的!

      回复
    1. Xiaoxia 文章作者

      您好!新版本准备出了。新版本将会完美支持Youtube!
      我会让它支持http和socks代理的,发布的时候通知你吧,谢谢支持:)

      回复
  2. 清风剑

    很好的idea,对于缓冲池的设置有点疑问,youku的缓冲不是应该将当前点后的视频缓冲吗?为什么会要求将前面的都加载完呢?

    回复
    1. Xiaoxia 文章作者

      你好,你的说法是对的。缓冲的确是从当前点开始缓冲的,那个是涉及到跳选视频的范畴,我文章里没有提及到。
      现在遇到比较棘手的问题是,youtube和youku在跳选视频的时候,同时启用了断点续传的时候,两者的处理方式都不一样。好像是youku的有问题,在跳选+设置断点续传的时候,得到的是黑屏。

      回复
  3. leeyu

    hello,有个问题想问你;我这个很简单的程序是这样的:
    一个服务器,每次来一个请求后fork一个进程来处理它,在子进程中把listenfd关了,而主进程继续close(connectfd)后再accept,但是情况出现了。。。每次accept后都会出现一个错误,找了很久都没有发现问题” accept error: Socket operation on non-socket “(注:不是网上那种没有匹配括号的低级毛病。。。)

    回复
      1. leeyu

        这问题我解决了。。。是子进程在处理完请求后没exit而继续下一次循环到accept,这时之前主线程已经在accept上blocked了。。。所以子进程在accept时会出现那个错误。查了好久。。。

        回复
  4. alwayslearn

    請問大大的開發軟件是eclipse嗎?

    小弟想研究一下大大的代碼

    可以請大大稍稍解釋一下嗎@@?

    回复
        1. Xiaoxia 文章作者

          非常抱歉我之前写的代码很多都没有详细的注释。
          同时,我可能没有时间为你一一解读,但是对于你的问题,我回尽量回答的。

          回复
  5. alwayslearn

    先謝謝大大的回覆
    我先說一下我目前遇到的問題
    如附圖 這是在我解決dev C 不能使用thread.h的問題後所遇到的新問題
    我希望做到的是至少要先能夠編譯並執行 現在就卡在這
    我不知道這邊的程式碼的用途是?
    看起來應該是繼承出了甚麼問題 或是在執行環境設定上有錯誤
    希望大大幫我解答一下

    附上錯誤的圖片( http://ppt.cc/lRS~ )

    回复
    1. Xiaoxia 文章作者

      呃,可能是C++头文件引起的问题?

      其实,如果你看过我的那篇介绍这个的加速原理的话,你就可以用你最熟悉的语言编写一个出来,代码也不需要很多,在处理HTTP请求和缓冲区分配合并的时候可能需要一些技巧。

      回复
  6. iuse

    xiaoxia你好!感觉,某加速器的SuperStream连接复合技术,及一些网页加速器,也用到相似的技术。
    能移植到ipv6就更好了。另,附件无法下载了。

    回复
    1. Xiaoxia 文章作者

      TCP多连接复合的,我也做过,不过是帮人家一个网络加速的项目里做的,数据可以使用N个TCP连接传输。效果很不错,浏览网页速度会提高,因为不需要TCP三次握手,响应速度快了。

      回复
  7. testtouse

    版大請問一下 您的contentbuff.h contentbuff.cpp 可以為我解說一下嗎 我看不太懂
    ———————————-ac-
    #include “contentbuffer.h”

    ContentBuffer::ContentBuffer() { }
    ContentBuffer::~ContentBuffer() { }

    ———————————-
    #ifndef CONTENTBUFFER_H
    #define CONTENTBUFFER_H

    class HttpShrimp;
    struct ContentBuffer {
    HttpShrimp* worker;
    char * buffer;
    int bufferSize;
    int writePos;
    int readPos;
    unsigned int dataBegin;
    unsigned int dataEnd;

    ContentBuffer(int __size){
    this->bufferSize = __size;
    this->buffer = new char[__size+4];
    this->readPos = 0;
    this->writePos = 0;
    this->worker = 0;
    }
    ~ContentBuffer(){
    delete this->buffer;
    }
    };

    #endif // CONTENTBUFFER_H

    回复

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据