您现在的位置:首页 >> 图形媒体 >> 图形媒体 >> 内容

Delphi开发音乐播放器技术总结

时间:2011/9/3 15:03:44 点击:

  核心提示:(1)使用WinSocket来进行HTTP下载通常情况下,我们可以用Indy的TIdHTTP控件进行网络文件的下载:IdHTTP1.GetURL(‘http://www.sohu.com’);//即可...

(1) 使用WinSocket来进行HTTP下载

   通常情况下,我们可以用Indy的TIdHTTP控件进行网络文件的下载:

     IdHTTP1.GetURL(‘http://www.sohu.com’);         //即可下载指定的网页。

但是,在某些情况下,为了获取更高的性能或者更灵活的控制,我们有必要使用原生的windows Socket API来进行HTTP的下载。

 要使用Windows Socket API来进行下载,分如下的步骤进行:

首先进行的连接指定的服务器。

使用GetHostByName(‘www.sohu.com’)获取服务器的IP地址, 然后,创建socket  -> connect连接服务器。连接成功后,需要发送一个HTTP协议请求的包头。如果成功,则服务器会返回相应得数据。

一般来说,HTTP协议的请求分为Get和Post两种。其一般形式如下:

Get /Filename HTTP/1.1             //请求类型 请求文件  协议版本

Referer: http://www.sohu.com/   //参考地址

User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; MyIE 3.01)

Host: 202.XX.XX.XX                  //即刚才使用GetHostByName获取到的IP地址。

Accept: */*                                //可接收的文件类型

Connection: Close                   //是否需要保持连接

Range: bytes=0-1000             //获取文件的范围,支持断点续传的网站

如果获取成功,服务器将返回相应的信息。如果返回头中有2XX OK的标志,表明成功。如果为200 OK则表明该网站支持多线程。数据头后面即为请求的数据。

这里只是一个简单的数据包结构,真正通讯中可能还有一些其他的东西。要参考相应的帮助。

 

(2) 调用DirectShow接口进行影音文件的播放:

DirectShow很强大,但是也很复杂,现在仍然继续研究中,这部分暂不总结。PlaceHold... ^_^

 

(3) 线程池:

  这个概念听起来很唬人,但是,实际上,也没有想想中的那么难,但是,要做出一个真正高效、稳定、灵活的线程池出来,还是需要一定功底的。这里只是简单的说明下我使用的方法:在线程池创建时,即创建一定数量的线程,当有任务需要处理时,直接将其加入到线程池中运行。运行完成后,通知线程池管理线程更新线程状态。在线程池管理线程中使用了队列的方式来处理。保证了线程的先后顺序。其实,这种方法,对于任务比较小,然而比较频繁的地方使用。因为这样就避免了频繁的创建和销毁线程所带来的开销。一般在服务器端会用的比较多,我们的聊天服务器就是这样的。

(4) 简单内存池:

其实,这个也是很简单的。但还是那句话,要想做的高效,稳定,灵活,还是要经过一些时间的研究和优化的。

一般情况下,编译器都有自己的内存管理器。但是,在性能要求比较高的情况下,比如需要频繁的分配内存的情况下,特别是服务器程序,可以使用内存池来提高内存分配的速度,同时,还可以减少内存碎片的产生。

对于内存块的分配大小不等的情况下,内存池采用平衡二叉树结构来保存分配的内存。每个结点的数据保存如下:

pMemNode = ^TMemNode;
      TMemNode = record
         FIsUsed: Boolean;     //whether is used

  FSize: int64;          //Memory Size

  FMem: Pointer;        //Pointer to memory allocated

  FLeft: pMemNode;     //Left leaf

  Fright: pMemNode;    //Right leaf

End; 600) this.width = 600;">

而对于内存块的大小相等的情况下,可以使用双向链表来保存。

每个结点的数据保存结构如下:

pMemNode = ^TMemNode;

TMemNode = record

  FIsUsed: boolean;         //Whether is allocated

  FSize: integer;            //Memory Size

  FMem: Pointer;           //Pointer to memory allocated

  FPrev: pMemNode;        //Pointer to parent node

  FNext: pMemNode;        //Pointer to next node

End;

600) this.width = 600;">

分配时,可以查到到第一个FIsUsed为false的结点返回即可。这个也可以进行优化,就是将它变成连个链表,一个保存未分配的节点,另一个保存未分配的内存结点指针头。

(5) 异步存储

在一个多线程下载程序中,如果有n个线程,需要同时对同一个文件进行存储操作,那么就必须进行同步。也可以为每个线程产生1个临时文件,等全部下载完成后再合并成一个文件。在多线程下载中,如果有9下载线程同时需要去写同一个文件,如果A线程正在写,那么其它线程就必须等待。如果我们将存储任务添加到保存线程队列中(添加过程和保存文件操作相比所用的时间可以忽略),由保存线程去处理,就可以减少等待时间。毕竟写文件所用的时间,比对一个链表进行读写慢的多。同时,可以在保存线程中申请一定的内存,先将需要保存的内容保存在内存流中,等到全部完成后,再保存到文件,这样,所有的操作均在内存中进行,减小了磁盘读写,对于磁盘起到一定的保护作用。

600) this.width = 600;">

作者:James.Zhai 来源:原创
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
本类推荐
  • 没有
本类固顶
  • 没有
  • 盒子文章(www.2ccc.com) © 2017 版权所有 All Rights Reserved.
  • 沪ICP备05001939号