著录项信息
专利名称 | 一种实现零拷贝发送流媒体数据的方法及系统 |
申请号 | CN200810142292.7 | 申请日期 | 2008-08-04 |
法律状态 | 权利终止 | 申报国家 | 中国 |
公开/公告日 | 2009-01-07 | 公开/公告号 | CN101340574 |
优先权 | 暂无 | 优先权号 | 暂无 |
主分类号 | H04N7/24 | IPC分类号 | H;0;4;N;7;/;2;4;;;H;0;4;N;7;/;1;7;3;;;H;0;4;L;2;9;/;0;8查看分类表>
|
申请人 | 中兴通讯股份有限公司 | 申请人地址 | 广东省深圳市南山区高新技术产业园科技南路中兴通讯大厦法务部
变更
专利地址、主体等相关变化,请及时变更,防止失效 |
权利人 | 中兴通讯股份有限公司 | 当前权利人 | 中兴通讯股份有限公司 |
发明人 | 王魏强;朱红军;程剑 |
代理机构 | 暂无 | 代理人 | 暂无 |
摘要
本发明公开了一种实现零拷贝发送流媒体数据的方法及系统,基于Linux的网络协议栈,其方法包括:在流媒体服务器接收到用户设备的数据请求时,进行发送数据的系统调用,将流媒体数据从磁盘空间读入用户数据缓存中;将用户数据缓存中存放的流媒体数据打包成实时传输协议数据包,对该实时传输协议数据包采用头部和载荷分离的流媒体数据包的发送。本发明方法及系统由于充分利用了网卡的DMA功能和SG(Scatter/Gather,分散/汇聚)功能,实现零拷贝发送流媒体数据的方式,与Linux内核现有的网络协议栈相比,实现了头部和载荷分离的流媒体数据包的发送,减少了将流媒体数据进行RTP打包过程中所需的一次数据拷贝操作。
1.一种实现零拷贝发送流媒体数据的方法,基于Linux的网络协议栈,其包括以下步骤:
A、在流媒体服务器接收到用户设备的数据请求时,进行发送数据的系统调用,将流媒体数据从磁盘空间读入用户数据缓存中;
B、将用户数据缓存中存放的流媒体数据打包成实时传输协议数据包;在内核空间为每一个待发送的实时传输协议数据包分配内核缓冲结构,该结构的数据由两部分组成:一部分是临时分配的内核缓冲区,包含所述实时传输协议数据包的头部;另一部分是临时映射的用户缓冲区,包含所述实时传输协议数据包的载荷;利用网卡的分散/汇聚功能和直接内存访问功能,分别将这两部分内核缓冲结构映射到网卡的发送缓冲区,调用网卡驱动模块的发送函数完成流媒体数据的零拷贝发送。
2.根据权利要求1所述的方法,其特征在于,当流媒体服务器需要处理多个用户请求时,通过一次系统调用给每个用户发送一个流媒体数据包。
3.根据权利要求2所述的方法,其特征在于,所述网络协议栈提供包括以下套接字编程接口:用于创建套接字的socket,用于关闭套接字的close,用于实现零拷贝发送流媒体数据的sendmsg系统调用。
4.一种实现零拷贝发送流媒体数据的系统,基于Linux的网络协议栈,设置包括一流媒体服务器以及通过网卡与该流媒体服务器相连接的用户设备,其特征在于,所述流媒体服务器在硬件设备与用户进程之间设置为内核空间,在该内核空间内的网卡驱动程序之上设置有网络协议栈;所述网络协议栈给用户进程提供套接字编程接口,所述套接字编程接口包括:用于创建套接字的socket,用于关闭套接字的close,用于实现零拷贝发送流媒体数据的sendmsg;
所述媒体服务器,用于接收到用户设备的数据请求时,进行发送数据的系统调用,将流媒体数据从磁盘空间读入用户数据缓存中;以及,将用户数据缓存中存放的流媒体数据打包成实时传输协议数据包,在内核空间为每一个待发送的实时传输协议数据包分配内核缓冲结构,该结构的数据由两部分组成:一部分是临时分配的内核缓冲区,包含所述实时传输协议数据包的头部;另一部分是临时映射的用户缓冲区,包含所述实时传输协议数据包的载荷;利用网卡的分散/汇聚功能和直接内存访问功能,分别将这两部分内核缓冲结构映射到网卡的发送缓冲区,调用网卡驱动模块的发送函数将流媒体数据发送至所述用户设备;
用户设备,用于向所述媒体服务器发送数据请求,以及,接收所述媒体服务器发送的流媒体数据。
5.根据权利要求4所述的系统,其特征在于,所述流媒体服务器采用批量发送技术,用于一次sendmsg系统调用发送多个数据包。
技术领域\n本发明属于计算机应用领域的一种网络通信方法及系统,具体涉及的是一种基于Linux的网络协议栈实现零拷贝发送流媒体数据的方法及系统。\n背景技术\n现有技术中,在基于Linux操作系统的流媒体服务器应用中,需要将大量的流媒体数据从磁盘上传递到网络上。当流媒体数据从磁盘上到网络上传输时,要在不同的系统空间中进行多次传递。\n传递的流程主要包括如下3个部分:(1)将流媒体数据从磁盘空间读入用户数据缓存中;(2)将用户数据缓存中存放的流媒体数据打包成RTP(Real-time Transport Protocol,实时传输协议)数据包存入用户发送缓存中;(3)将用户发送缓存中存放的RTP数据包通过UDP(User DatagramProtocol,用户数据报协议)网络套接字发送出去。\n在Linux操作系统中,用户进程通过调用直接输入输出接口系统调用,可以用来读取磁盘数据,该系统调用将磁盘数据通过DMA(Direct MemoryAccess,直接内存访问)机制直接写入到用户缓存中;通过调用UDP网络套接字相关系统调用接口,可以用来发送RTP数据包,该系统调用将RTP数据包从用户空间复制到内核空间,进行相应的封装,通过DMA机制映射到网卡的发送缓冲区,网卡将该RTP数据包发送出去。\n在现有技术的这种方式下,用户进程从磁盘读入流媒体数据可以实现零拷贝,但将流媒体数据打包成RTP数据包需要进行数据的拷贝,发送RTP数据包时也需要将其从用户空间拷贝到内核空间。\n此外,用户进程每发送一个数据包,就需要使用一次系统调用,每次系统调用需要先从用户态切换到内核态,系统调用返回后,再从内核态切换到用户态。在流媒体服务器负荷较重的情况下,会触发大量的数据拷贝和上下文切换操作,极大地消耗系统的CPU资源,降低系统的处理能力。\n由此可见,流媒体数据包发送过程中的开销主要产生在用户进程、操作系统、网卡驱动等不同层次的数据组织、数据拷贝和数据传输上。如何有效地减少数据拷贝和系统调用的次数,降低CPU的消耗,提高系统的处理能力,对于提升流媒体服务器的性能,具有非常重要的影响。\n现有技术还有待于改进和发展。\n发明内容\n本发明的目的在于提出一种基于Linux的网络协议栈实现零拷贝发送流媒体数据的方法及系统,在不影响Linux系统原有网络协议栈的情况下,尽量减少数据拷贝和系统调用引起的CPU消耗,提高系统的处理能力。\n为实现上述目的,本发明的技术方案包括:\n一种实现零拷贝发送流媒体数据的方法,基于Linux的网络协议栈,其包括以下步骤:\nA、在流媒体服务器接收到用户设备的数据请求时,进行发送数据的系统调用,将流媒体数据从磁盘空间读入用户数据缓存中;\nB、将用户数据缓存中存放的流媒体数据打包成实时传输协议数据包;在内核空间为每一个待发送的实时传输协议数据包分配内核缓冲结构,该结构的数据由两部分组成:一部分是临时分配的内核缓冲区,包含所述实时传输协议数据包的头部;另一部分是临时映射的用户缓冲区,包含所述实时传输协议数据包的载荷;利用网卡的分散/汇聚功能和直接内存访问功能,分别将这两部分内核缓冲结构映射到网卡的发送缓冲区,调用网卡驱动模块的发送函数完成流媒体数据的零拷贝发送。\n所述的方法,其中,当流媒体服务器需要处理多个用户请求时,通过一次系统调用给每个用户发送一个流媒体数据包。\n所述的方法,其中,所述网络协议栈提供包括以下套接字编程接口:用于创建套接字的socket,用于关闭套接字的close,用于实现零拷贝发送流媒体数据的sendmsg系统调用。\n一种实现零拷贝发送流媒体数据的系统,基于Linux的网络协议栈,设置包括一流媒体服务器以及通过网卡与该流媒体服务器相连接的用户设备,其中,所述流媒体服务器在硬件设备与用户进程之间设置为内核空间,在该内核空间内的网卡驱动程序之上设置有网络协议栈;所述网络协议栈给用户进程提供套接字编程接口,所述套接字编程接口包括:用于创建套接字的socket,用于关闭套接字的close,用于实现零拷贝发送流媒体数据的sendmsg;\n所述媒体服务器,用于接收到用户设备的数据请求时,进行发送数据的系统调用,将流媒体数据从磁盘空间读入用户数据缓存中;以及,将用户数据缓存中存放的流媒体数据打包成实时传输协议数据包,在内核空间为每一个待发送的实时传输协议数据包分配内核缓冲结构,该结构的数据由两部分组成:一部分是临时分配的内核缓冲区,包含所述实时传输协议数据包的头部;另一部分是临时映射的用户缓冲区,包含所述实时传输协议数据包的载荷;利用网卡的分散/汇聚功能和直接内存访问功能,分别将这两部分内核缓冲结构映射到网卡的发送缓冲区,调用网卡驱动模块的发送函数将流媒体数据至所述用户设备;\n用户设备,用于向所述媒体服务器发送数据请求,以及,接收所述媒体服务器发送的流媒体数据。\n所述的系统,其中,所述流媒体服务器采用批量发送技术,用于一次sendmsg系统调用发送多个数据包。\n本发明所提供的一种实现零拷贝发送流媒体数据的方法及系统,由于充分利用了网卡的DMA功能和SG(Scatter/Gather,分散/汇聚)功能,实现零拷贝发送流媒体数据的方式,与Linux内核现有的网络协议栈相比,实现了头部和载荷分离的流媒体数据包的发送,减少了将流媒体数据进行RTP打包过程中所需的一次数据拷贝操作。\n附图说明\n图1是通过本发明实现的网络协议栈进行零拷贝发送流媒体数据的示意图;\n图2所示是本发明系统的结构示意图。\n具体实施方式\n以下结合附图,将对本发明各较佳实施例进行更为详细的说明。\n本发明基于Linux的网络协议栈实现零拷贝发送流媒体数据的方法中,利用了原有的Linux网络协议栈,该网络协议栈利用内核模块机制实现,所述内核模块的加载和卸载都不会影响Linux内核原有的网络协议栈。本发明所述实现零拷贝发送流媒体数据的系统中,其包括流媒体服务器和与该流媒体服务器相连接的一用户设备,如图2所示,所述流媒体服务器设置有网卡与所述用户设备通讯连接。所述网卡支持DMA功能和SG(Scatter/Gather,分散/汇聚)功能。\n本发明所述方法及系统中,所述流媒体服务器的硬件设备包括网卡和硬盘,如图1所示,在硬件设备与用户进程之间是Linux内核空间,在该内核空间内的网卡驱动程序之上设置有网络协议栈,所述网络协议栈给用户进程提供套接字编程接口,所述套接字编程接口主要包括socket、close、sendmsg等系统调用,其中socket用于创建套接字,close用于关闭套接字,sendmsg用于实现零拷贝发送流媒体数据。\n本发明方法及系统的硬件环境要求网卡具有DMA功能和SG功能,软件环境为网络功能正常的Linux内核。为了实现零拷贝发送流媒体数据的功能,本发明方法及系统在原有Linux内核的基础上创建了基于AF_DATALINK套接字类型的DATALINK网络协议栈。该协议栈给用户进程提供AF_DATALINK类型的套接字编程接口,包括socket、close、sendmsg等系统调用。其中socket系统调用用于创建套接字,close系统调用用于关闭套接字,sendmsg系统调用用于以零拷贝的方式把流媒体数据以RTP数据包封装方式发送出去。\n现有技术的sendmsg系统调用原有标准语义不能够实现本发明的功能,必须对其进行重新定义,下面给出了本发明方法及系统sendmsg系统调用的定义及其解释:\nssize_tsendmsg(int socket,const struct msghdr*msg,int flags);\n功能:\n通过套接字进行零拷贝发送流媒体数据。\n输入输出参数:\nsocket 使用socket系统调用创建的AF_DATALINK套接字;\nmsg->msg_name 暂时不用。\nmsg->msg_namelen 暂时不用。\nmsg->msg_iov 输入参数。指向struct iovec数组的指针。每个structiovec结构包含待发送数据的缓冲区地址和长度。\nmsg->msg_iovlen 输入参数。用于存放msg_iov所指struct iovec数组的长度。\nmsg->msg_control 输入输出参数。输入时用于存放每个流媒体数据包的控制信息,包括IP地址、UDP端口、RTP负载类型等;输出时用于返回发送错误数据包的索引和错误码。\nmsg->msg_controllen 输入参数。用于存放msg_control信息的总长度。\nmsg->msg_flags 暂时不用。\nflags 暂时不用。\n返回值:\n如果数据包都没有发送成功,则返回-1,并设置错误码errno。\n如果数据包部分或者全部发送成功,则返回成功发送的数据包的数目,没有发送成功的数据包的索引和相应的错误码通过输出参数返回。\n构成RTP数据包的信息存放在参数msg中,msg_iov字段存放待发送RTP数据包的载荷信息,包含用户数据缓冲区的地址和长度信息,作为RTP数据包的载荷;msg_control字段存放待发送RTP数据包的头部信息,包含IP地址、端口号、RTP负载类型等,用于生成RTP数据包的头部。\n如图1所示,本发明方法在sendmsg系统调用时,在内核空间为每一个待发送的RTP数据包分配内核缓冲结构sk_buff,该结构的数据由两部分组成:一部分是临时分配的内核缓冲区,包含流媒体RTP数据包的头部,是根据msg_control中包含的头部信息生成;另一部分是临时映射的用户缓冲区,包含RTP数据包的载荷,是根据msg_iov中包含的载荷信息得到。利用网卡的SG功能和DMA功能,分别将这两块缓冲区映射到网卡的发送缓冲区,调用网卡驱动模块的发送函数完成流媒体数据的零拷贝发送。上述映射过程为现有技术所熟知,在此不再赘述。\n本发明方法及系统的流媒体服务器在处理单个用户请求时,通过使用AF_DATALINK套接字和一次sendmsg系统调用,就可以实现零拷贝发送流媒体数据。\n当流媒体服务器需要处理多个用户请求时,除了可以类似单个用户请求时使用零拷贝发送流媒体数据,还可以通过减少系统调用的次数进一步优化系统性能:这主要归功于对sendmsg系统调用的参数msg的语义重定义,其成员msg->msg_iov指向一批数据包缓冲区,成员msg->msg_iovlen表示数据包缓冲区的个数,这样一次系统调用就可以发送一批流媒体数据包。在实际的应用中,可以在一次sendmsg系统调用中给每个用户发送一个流媒体数据包,以此来减少sendmsg系统调用的次数,从而优化系统性能。\n本发明方法及系统充分利用了网卡的DMA功能和SG功能,实现了零拷贝发送流媒体数据,与Linux内核现有的网络协议栈相比,本发明方法及系统利用网卡的SG功能,实现了头部和载荷分离的流媒体数据包的发送,减少了将流媒体数据进行RTP打包过程中所需的一次数据拷贝操作。\n同时,利用网卡的DMA功能,实现了网卡驱动模块直接使用用户缓冲区进行数据包的发送,减少将流媒体数据从用户空间拷贝到内核空间所需的一次数据拷贝操作。\n本发明方法及系统还采用批量发送技术,实现了一次系统调用发送一批数据包的功能,避免了发送一个数据包就需要一次系统调用的情况,减少了向多用户发送流媒体数据时系统调用的开销。所述批量发送技术的具体实现也是现有技术本领域技术人员所了解的,因此不再赘述。\n需要说明的是,上述网络协议栈的实现是通过软件实现的,系统调用的实现也是现有技术软件实现中所熟知的,因此不再赘述其具体实现过程,为本领域技术人员所熟知。\n同时,需要指出的是,上述针对本发明各较佳实施例的描述较为详细和具体,并不能因此而认为是对本发明专利保护范围的限制,本发明的专利保护范围应以所附权利要求为准。
法律信息
- 2017-09-22
未缴年费专利权终止
IPC(主分类): H04N 7/24
专利号: ZL 200810142292.7
申请日: 2008.08.04
授权公告日: 2010.09.08
- 2010-09-08
- 2009-02-25
- 2009-01-07
引用专利(该专利引用了哪些专利)
序号 | 公开(公告)号 | 公开(公告)日 | 申请日 | 专利名称 | 申请人 | 该专利没有引用任何外部专利数据! |
被引用专利(该专利被哪些专利引用)
序号 | 公开(公告)号 | 公开(公告)日 | 申请日 | 专利名称 | 申请人 | 该专利没有被任何外部专利所引用! |