网络电话软件设计论.doc_第1页
网络电话软件设计论.doc_第2页
网络电话软件设计论.doc_第3页
网络电话软件设计论.doc_第4页
网络电话软件设计论.doc_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

摘要网络电话,也称为IP电话,近几年它的发展非常之迅速。本文设计并实现了一个计算机到计算机的网络电话的软件模型,既能实现多人之间的文本聊天,又能实现两人之间的语音聊天。其中详细讲解了软件设计中的重点和难点,分析了软件中语音的采集和播放,语音的网络传输等一些关键技术的实现方法和注意事项,并指出了软件的不足和进一步工作。在局域网上用此软件来做通话实验,音质和时延都达到了电话的效果,说明此软件达到了IP电话的基本要求。关键词网络电话 语音 网络AbstractNetwork telephone, called IP telephone too, its development is very fast in recent years. This text design and realize one computer network software model of phone to reach computer, can not only can realize the voice-enabled chat between two people the text between many people chats but also. Among them has explained focal point and difficult point in software design in detail , has analysed the collection of the pronunciation in the software and broadcast, some key technology implementation method and precautions that the network of the pronunciation transmits ,etc., have pointed out the deficiency of the software and work further. At LAN it make conversation experiment coming with software,tone quality and when prolong not getting the result of telephone , prove this software has reached the basic demand of IP telephone. Keyword Network telephone Pronunciation Network目录摘要1abstract2目录3第一章 前言4第二章 软件设计52.1软件的需求分析52.1.1整体结构52.1.2信令系统的实现52.1.3语音通信的实现62.2软件的功能模块简介6第三章 Socket通讯介绍73.1 Socket的基本概念73.2 Socket通信实现原理7第四章 语音通讯介绍94.1语音通信的原理94.2语音数据的网络传输104.3对单工声卡的支持12第五章 软件实现原理135.1通信模块的实现135.2音频模块的实现135.2.1语音的采集和播放:145.2.2 VC+实现语音数据的网络传输15第六章 软件具体实现176.1软件的页面设计176.1.1 服务器端的界面设计176.1.2 客户端的界面设计186.2软件的运行方式186.3软件的具体实现196.3.1处理客户端请求建立与服务器的连接196.3.2处理客户端向另一客户端发送连接请求196.3.3处理客户端的响应请求206.3.4处理客户端的通信206.3.5处理客户端断开通话连接的请求206.3.6处理客户端断开与服务器的连接20结论21致谢22第一章 前言Internet是当今应用最广泛、发展最迅速的通信网络。这是基于数据包方式的数据分组交换方式,用户数据被封装在分组中,而分组还包含一些附加信息用于网络中的路由选择、差错纠正、流量控制等。数据包各自独立地在网络中传递,由于网络状况的变化和经历路径的不同,数据包到达目的地的时间是不固定的、非实时的。故此,一般来说互联网较适用于数据的传输。但是,我们知道视频、音频信号经过模数转换后也可以作为数据在互联网上传递,因此将语音采样,量化变为数字信号,然后打包从网络上传输,双方也可以进行通话,这就是网络电话。网络电话是对模拟语音信号经过模数转换,进行编码压缩后,按一定的打包规则将压缩帧转换成IP数据包通过数据网进行传输,在目的地经过数据解压、数模转换复原成话音,从而达到语音通信的目的。由于数据网是采用统计时分的方式分配、使用网络资源,任何通信实体都不可能独占某一信道,所以网络电话可以大大提高网络资源的利用率,降低运营成本。网络电话的初次亮相是在1995年初,VocalTec公司推出了一种Internet Phone客户软件。虽然当时该公司还没有提出在IP上传输话音的概念,但这确实是网络电话第一次成功的商业化和市场化。在此之前,IP上的话音传输极为困难,VocalTec的第一个产品用于LAN上的两台PC相互通话。现已有多家网络公司开始利用因特网正式提供国际国内的长途电话服务。特别在美国,此类业务开展得更为广泛。类似的技术也可用于长途传真(EFax)等电信服务项目。由于全球范围内的因特网通信费用大大低于通常的电信长途费用,众多的用户已开始使用通过因特网的长途电话服务。 基于实验和研究的目的,本文实现了一个从计算机到计算机的网络电话的软件。软件的开发环境为Windows XP平台,开发工具采用Visual C+ 6.0。本软件能够在网络上实现两人之间的文本传输和两人之间的语音对话,但支持多人在线。下文将对本软件展开分析。第二章 软件设计2.1软件的需求分析2.1.1整体结构 本系统从逻辑上分为2个部分:客户端和服务器端。 客户端与服务器端之间的关系如图1所示。服务器端的数据库中包含了所有用户的资料。例如用户的名称、IP地址、当前状态等信息。服务器端程序利用Winsock控件来监听客户端发来的请求,对接收到的客户端发来的请求进行处理,提取出命令字及参数,按照定义好的命令字完成相应的工作。服务器完成的任务基本上都是被动的,大部分是响应客户端发出的请求。客户端模块负责建立起连接之后的语音通讯功能。该模块从声卡采集音频数据并压缩,然后把数据流发送到服务器并转发到对方主机。同时该模块还负责对接收到的语音数据流进行解压缩并利用声卡播放出来的任务。 2.1.2信令系统的实现 在C/S模式中,消息命令字起到了非常重要的作用,服务器端与客户端之间通过发送以消息命令字开头的包含指定消息的字符串来实现沟通。收到指定的消息命令字就去执行该消息命令字对应的操作。消息命令字可以是以字节形式组成的,也可以是以比特位形式组成的。本系统采用的是用固定长度的字符串组成的消息命令字,通过定义特殊的消息命令字(信令)来控制系统工作。2.1.3语音通信的实现 为了实现语音的采集,使用了vtRecWave类和vtPlayWave类,先为他开辟了一块连续的缓冲区,用vtRecWave类的VTRecordWave:StartRecord(void)方法来实现语音的采集。为了实现语音的播放,首先把采集到的经过压缩后的语音取出来。然后以流的方式,通过局域网传送到另一个主机的缓冲区。最后,通过vtPlayWave类的VTPlayWave:StartPlay(void)方法进行播放。 网络传输可以使用各种方法实现,不同的方法需要不同的处理技巧。这里就不一一说明了。2.2软件的功能模块简介软件的主要功能是文本聊天和语音聊天。文本聊天的实现方法:1 建立与服务器的连接。客户端输入用户名,选择本机的通信协议,并且输入正确的服务器名称之后才能向服务器发送建立连接请求。2当服务器收到客户端的请求之后,服务器将此客户端的状态置为AVAILABLE。并将该客户端添加到用户列表。3当一客户端请求与另一客户端建立连接时,客户端在联系人一栏中选择想要聊天的对象。服务器收到此信息后,首先查看用户列表,如果被访问用户存在并且空闲,此时服务器发信息至另一客户端,当另一客户端同意进行通话时,服务器将两个客户端的状态置为SESSION SETUP。此时被请求的客户端弹出一个对话框,如果接受连接,此时服务器把两个客户端的状态置为IN SESSION.4 当某一客户端想要断开连接,则只需在用户列表中选择NO ONE TO TALK 。此时断开与另一个客户端的连接。服务器发信息至另一客户端,通知其对方客户端已经断开与之的连接。此时服务器更新用户列表。5当客户端想与服务器端断开连接时,只需按关闭按钮。此时即与服务器断开连接。服务器更新用户列表。语音聊天的实现方法:1建立与服务器的连接。客户端输入用户名,选择本机的通信协议,并且输入正确的服务器名称之后才能向服务器发送建立连接请求。2 建立连接后,客户端选中语音聊天复选框,双方需要有只有两个客户端同时选中该复选框才能进行语音聊天。第三章 Socket通讯介绍3.1 Socket的基本概念1、Socket,也就是俗称的套接字。 2、Sun Java中的定义:是运行在网络上的两个程序间双向通讯连接的末端,它提供客户端和服务器端的连接通道。Socket绑定于特定端口这样TCP层就知道将数据提供给哪个应用程序。 3、字面上的理解,Socket的意思是插座、孔,你还可以把它形象地理解为打电话用的电话机,你从听筒里听到对方声音,同时将声音通过话筒传给对方。套接字(Socket)最初是由加利福尼亚大学Berkeley分校为UNIX操作系统开发的网络通信接口.随着UNIX操作系统的广泛使用, 套接字成为当前最流行的网络通信应用程序接口之一.20世纪90年代初期,由Sun Microsystems, JSB Corporation,FTP software,Microdyne和Microsoft等几家公司共同制造了一套标准,即Windows Sockets规范.Windows Sockets API是 Microsoft Windows的网络程序设计接口,它在继承了Berkeley Sockets主要特征的基础上,又对它进行了重要扩充.这些扩充主要是提供了一些异步函数,并增加了符合Windows消息驱动特性的网络事件异步选择机制.这些扩充有利于应用程序开发者编制符合Windows编程模式的软件,它使在Windows下开发高性能的网络通信程序成为可能.Sockets实际上是指一个通信端点,是网络的基本构件.借助于它,用户所开发的Socket应用程序,可以通过网络与其他Socket应用程序进行通信.它是可以被命名和寻址的通信端点,使用中的每一个套接字都有其类型和一个与之相连的进程. 套接字存在通信区域(通信区域又称地址簇)中. 套接字只与同一区域中的套接交换数据(跨区域时,需要执行某些转换进程才能实现).Windows中的套接字只支持一个域_网际域.套接字具有类型,Windows Socket 1.1版本支持两种套接字:流套接字(SOCK_STREAM)和数据报套接字(SOCK_DGRAM).3.2 Socket通信实现原理TCP/IP协议的核心部分是传输层协议(TCP,UDP),网络层协议(IP)和物理接口层,这三层通常是在操作系统内核中实现.因此用户一般不涉及.编程时,编程界面有两种形式:一种形式是由内核心直接提供的系统调用:另一种形式是使用以库函数方式提供的各种函数.前者为核内实现,Socket与TCP/IP协议的关系如图所示.应用程序1应用程序2网络应用编程界面(SOCKET)TCP/IP核心协议物理介质Socket与TCP/IP协议关系在TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器模式(Client/Server model).该模式的建立基于以下两点:一点是非对等作用;另外一点是通信完全是异步的.客户机/服务吕模式 在操作过程中采取的是主动请示方式.首先服务器要先启动,并根据请示提供相应服务,过程如下所述.(1)打开一通信通道并告知本地主机,它愿意在某一个公认地址上接收客户请求.(2)等待客户请求到达端口.(3) 接收到重复服务请求,处理该请求并发送应答信号.(4) 返回第二步,等待另一客户请求.(5)关闭服务器.客户方:打开一通信通道,并连接到服务器所在主机的特定端口.向服务器发送服务请求报文,等待并接收应答;继续提出请求请求结束后关闭通信通道并终止.在MFC中,Microsoft为套接口提供了相应的类CAsyncSocket和Csocket.CAsyncSocket提供基于异步通信的套接口封装功能,Csocket则是由CasyncSocket派生,提供更加高层次的功能.例如可以将套接口上发送和接收的数据和一个文件对象(CSocketFile)关联起来,通过读写文件来达到发送和接收数据的目的,此外Csocket提供的通信为同步通信,数据未接收到或是未发送完之前调用不会返回.与此同时,通过MFC类开发者可以不考虑网络字节顺序和忽略掉更多的通信细节.在一次网络通信/连接中有以下几个参数需要设置:本地IP地址-本地端口号-对方端口号-对方IP地址左边两部分称为一个半关联,当与右边两部分建立连接后就称为一个全关联.在这个全关联的套接口上可以双向交换数据.如果是使用无连接的通信则只需要建立一个半关联,在发送和接收时指明另一半的参数就可以了, 所以可以说无连接的通信是将数据发送到另一台主机的指定端口.此外不论有连接还是无连接的通信都不需要双方的端口号相同.第四章 语音通讯介绍4.1语音通信的原理要实现点对点语音通信,原理非常简单,只要针对一个点实现话音的实时采集、处理、播放,同时能进行可靠的传送和接收,这样两点一连便可通话。对于前者,采用Windows MDK的低层音频服务比较合适,因为低层音频服务中的回调机制为我们提供了很大的方便。当应用程序不断向设备驱动程序提供音频数据时,设备驱动程序控制音频设备在后台完成录音和放音的具体操作,通过回调机制,我们又可以检测到什么时候用完一个数据块,并及时传送下一个数据块,从而保证了声音的连续,有了这种单机上的实时采集、回放功能后,接下来的工作就是在网络上传送话音数据。在点对点网络传输方面,选择面向连接的TCP协议,TCP传输协议自动处理分组丢失和交付失序问题,这样我们不用为这些问题操心,只需很好地利用这个连接,在采集话音回放之前一方面将自己的话音传给网络,另一方面接收网络传来的话音,这样便实现了点对点语音通信。其结构框图如下:声音的采集和播放都是在操作这个typedef struct wavehdr_tag LPSTR lpData; /* pointer to locked data buffer */ DWORD dwBufferLength; /* length of data buffer */ DWORD dwBytesRecorded; /* used for input only */ DWORD dwUser; /* for clients use */ DWORD dwFlags; /* assorted flags (see defines) */ DWORD dwLoops; /* loop control counter */ struct wavehdr_tag FAR *lpNext; /* reserved for driver */ DWORD reserved; /* reserved for driver */ WAVEHDR, *PWAVEHDR, NEAR *NPWAVEHDR, FAR *LPWAVEHDR;音频数据块结构,实际上主要用到的就是第一个成员变量lpData, 所以我们只要在分配缓冲区(内存)的同时相应分配WAVEHDR数据块结构,然后将缓冲区的指针赋给对应的数据块结构的成员变量 lpData,这样当一个缓冲区填满后,也就是一个音频数据块填满了,通过消息机制就可以在消息函数中进行处理和播放,播放完后又可通过消息函数把缓冲区再送给音频设备输入驱动程序,继续进行采集并播放,当你一次性分配多个缓冲区和数据块结构并赋给音频设备输入驱动程序后,至于把哪个缓冲区填满,然后再把哪个空缓冲区赋给设备输入驱动程序,不需人为干预,完全由Windows控制,这就是一种用动态循环缓冲区实现话音的实时采集、播放的简单而巧妙的办法。 对于声音的传送和接收主要是采用面向连接的TCP协议,并用Windows Socket进行网络编程实现,但首先要将发送和接收的函数接口放在 OnMmWimData(.)函数中,这样才能做到采集数据块填满后被发送,接收的数据收到后被播放。 Windows Socket对于从事过网络编程的人来说应该不陌生,因为我们要实现点对点通信,所以得把客户和服务器模式融合为一种模式,让服务器可以做客户,客户也可以做服务器,从而使双方都有呼叫对方和接受对方呼叫的能力,这只需增加一个监听Socket就行了。一旦呼叫连接建立成功,便在两个点之间建立了一个数据流,即使双方不讲话,每个点也在不停地收、发数据,一方有话音自然就随着这个数据流传给了对方,所以关键的问题就是怎样读取话音数据流,因为TCP提供的流式服务是不保证边界的,当发送方想一次发送 4000个字节时,调用语句Send(sBuffer,4000),并不能保证一定能发送出4000个字节;同样,接收方准备一次接收发过来的数据,调用语句Receive(rBuffer,4000),也不能保证一定能接收4000个字节,因此实际一次发送和接收的字节数会是1到4000中的任何一个值,最坏的情况是只有1个字节。相反,如果用Send函数连续发送少量数据,比如一次发送400个字节,连续发送10次,接收方用Receive函数可能一次就把这4000个字节都接收下来了,而为了实现播放,我们希望调用一次发送函数就能把缓冲区大小的话音数据发送出去,调用一次接收函数就能把对方一次发送的话音数据准确接收下来,以便进行播放,所以一种比较简单实用的办法,就是利用TCP协议发送数据时为每个数据包加个标志头。 4.2语音数据的网络传输(1)实现语音的采集和播放,就是在发话方将声音通过麦克风和声卡采集成语音数据,在接收方通过声卡和耳机播放出来。(2)实现语音数据的压缩和解压缩,在发话方压缩采集的语音数据,在接收方解压缩。(3)实现语音数据在网络上的传输。(4)多用户之间的连接方式和控制。(5)软件整体结构和交互界面的设计。 考虑到软件的核心功能是传输语音,所以整个软件的设计应该围绕着语音传输来设计。首先分析语音传输的过程,如图一是一个单向的语音传输过程。发话方首先由声卡采集语音,将语音转换为数据,存入内存中,再通过CPU进行语音压缩算法的运算,将语音数据进行压缩,最后通过网卡将语音数据发送出去。接收方通过网卡接收到语音数据,首先由CPU采用解压缩算法将语音数据进行解压缩,然后通过声卡将数据转换为语音,通过耳机播放。此流程图实际上已经包含了上述问题中前三个问题的解答,当然这只是从理论上肯定了可行性,具体的实现后面还会进一步讨论。多个用户之间的互相连接通常可以采用两种方法,如图二和图三。第一种方法是设置一个服务器,所有的客户机都连接到服务器上,通过服务器互相连接。这种方法的好处是软件控制比较简单,用户的连接也比较方便,用户只需要知道服务器的IP地址就行了。但缺点也很明显,它较适合于公司的商业性质的软件,普通人员没有资金去专门购买和设置一个服务器,也没有时间和精力去管理和维护服务器。第二种方法是不要服务器,每两个用户之间都可以互相连接,只要知道对方的IP地址就可以去连接对方,同时别人只要知道你的IP地址,也可以与你连接,即每台计算机都既是服务器,又是客户机。采用这种方法的优缺点与第一种方法可以说是正好相反,不再赘述。也有某些比较完善的软件对这两种方法都予以采用,用户可以自行选择其中一种方法与其它用户进行连接。由以上分析,作者决定采用第二种方式进行计算机之间的连接,这样虽然增加了软件的复杂度,但符合我们的实际情况。在实际程序中,采用了一个链表来保存与之相连的用户的信息,充分利用了链表的无序性和动态的增加,删除特性来表示无序的用户的动态的连接和离开。这样也从理论上解决了第四个问题。软件的整体结构和数据流程如图四,用户交互界面用来响应用户的操作,提示用户重要的信息,显示文本,播放语音等,实现软件与用户的交互。用户可以通过键盘来输入文本,通过麦克风来输入语音。语音采集模块用来采集语音数据,将模拟语音信号转换为数字信号,在程序中为了减少通话的延迟时间,直接分配内存块,将采集的数据放在内存块中,以便压缩或传输。对语音的采集是通过调用声卡的API函数来完成。在本软件中语音的采样格式为WAVE_FORMAT_PCM,单声道,采样率为8K,样本量化率为16位,即每秒的语音数据有16K字节。数据传输模块采用VC的CSocket类,通过TCP/IP协议将放在内存块中的语音采集数据传输到接收方。语音播放模块将接收到的语音数据直接通过声卡把数字信号转换为模拟信号,进行播放。语音压缩模块首先对输入的语音帧进行高通滤波,去除信号中的直流分量和50Hz的成分,同时进行增益控制。再进行线性预测分析,提取线谱对参数,对线谱对进行预测和量化,利用线谱对参数构造共振峰感觉加权滤波器,对高通信号进行开环基音估计,在开环基音估计的基础上进行闭环基音估计,在已经取得的参数的基础上代入语音生成模型对激励码本进行搜索,提取激励参数。对各参数进行量化,编帧。本软件的压缩率达到了1/20的效果,即压缩后每秒的语音数据为0.8K字节。语音解压模块从语音帧中提取各参数代入语音生成模型,输出语音。至此我们已经搭起了整个软件的基本框架,对于软件的数据流程也已分析得比较透彻,下一步就是具体的实现了。4.3对单工声卡的支持声卡有单工声卡和双工声卡之分,双工声卡可以同时录音和放音,而单工声卡一个时间段只能从事一种工作,要么录音,要么放音。对IP电话来说,当然是要用双工声卡,才能达到电话的效果。但考虑到当前广大用户的计算机配置的都是单工声卡,本软件也加入了对单工声卡的支持。软件可以自动检测计算机的声卡,针对不同的声卡采用不同的工作方式。当声卡为双工声卡时,可以同时听和说,当声卡为单工方式时则用户可以控制,在听和说之间进行切换。具体的实现方法是,当一方为单工声卡时,首先通过网络通知对方,让对方有心理准备。然后在实际的通话过程中,一方进行切换时,就通知另一方,另一方也自动进行切换,进入对应的方式。即一方为说时,另一方就自动为听,反之亦然,这样双方就不会发生冲突。具体的编程实现比较复杂,但只要考虑周到,也并不困难,这里不再赘述。第五章 软件实现原理5.1通信模块的实现MFC中提供了封装的Socket类,它提供了全面的由事件驱动的Socket通信能力。程序必须按要求通过此Socket发送和接收数据。Winsock使用的是TCP协议或UDP协议,允许建立并保持一个到远程计算机上的连接,且可以在连接结束之前实时地进行数据交换。用户仅通过设置属性并借助事件处理就能轻而易举地连接到一个远程的计算机上。使用Winsock时,通信的双方需要选定相同的协议。TCP协议适用于传送大容量、需要安全性保证的数据文件; 而UDP协议适用需要分别与很多下属通信,或建立的连接比较多且为时变的情况,如语音通信。Socket是面向客户/服务器模式设计的,它针对客户和服务器程序提供了不同的系统调用。同时它还分为面向连接和无连接两种类型。对于语音传输,由于语音对实时性要求高,所以采用无连接的形式。而对于信令和数据传输,对准确性要求比较高,通常采用面向连接的形式。5.2音频模块的实现IP电话音频功能的实现主要包括语音的录制和播放。因为在IP电话中采集实时的音频数据而不是WAVE文件,而且要把实时的语音数据传输出去,所以编程过程中采用了底层音频处理函数, 这些函数允许应用程序直接与底层驱动程序通信,对录制和播放提供更灵活的控制。对于波形设备来说,不论是录制还是播放波形,系统要处理的数据量都很大,为了少占用内存,底层服务函数以数据块为单位进行处理, 应用程序要自己分配内存,并将内存块的地址、大小等信息告诉底层音频驱动程序。首先介绍几个要用到的数据结构。WAVEFORMATEX结构定义了WAVE音频数据文件的格式。WAVEHDR结构定义了波形音频缓冲区。读出的数据首先要填充此缓冲区才能送音频设备播放,声音的采集和播放都是在操作这个音频数据块结构。 实际上主要用到的就是第一个成员变量lpData,所以只要在分配缓冲区(内存)的同时相应分配WAVEHDR数据块结构, 然后将缓冲区的指针赋给对应的数据块结构的成员变量lpData,这样当一个缓冲区填满后,也就是一个音频数据块填满了,通过消息机制就可以在消息函数中进行处理和播放,播放完后又可通过消息函数把缓冲区再送给音频设备输入驱动程序,继续进行采集并播放。当一次性分配多个缓冲区和数据块结构并赋给音频设备输入驱动程序后,至于把哪个缓冲区填满,然后再把哪个空缓冲区赋给设备输入驱动程序,不需人为干预,完全由Windows控制。在程序设计中可以使用两个数据块,交替进行,当正播放第一个缓冲区,就用第二个缓冲区接收。下面具体分析软件实现中的一些主要难点。5.2.1语音的采集和播放本软件中要把语音直接转换为数据,放在内存中,而不是存为语音文件,而且播放语音时,也是直接播放语音数据,而不是播放语音文件。这样的好处前面已经提到,即省略了读写硬盘的费时操作,提高了语音通话的实时性。要完成上述语音操作,编程语言中提供的容易使用的高级的多媒体语音函数是无法胜任的,只能用一些底层的语音函数来实现,这一类函数和结构的名字都以“wave”作为前缀。下面简要分析录音和放音的流程,考虑到两着的处理和流程基本上是类似的,本文就只以录音为例来分析,如图五为录音流程。录音的准备工作主要是三点,打开录音设备,获得录音句柄,指定录音格式,分配若干用于录音的内存,内存的大小和数量下文将进一步分析。开始录音时,先将所有内存块都提供给录音设备用来录音,录音设备就会依次将语音数据写入内存,当一块内存写满,录音设备就会发一个Window 消息MM_WIM_DATA给相应的窗口,通知程序作相关的处理,这时程序通常的处理是把内存中的数据进行复制,如写入文件等,在此我们的处理是把数据进行压缩和网络发送,然后把内存置空,返还给录音设备进行录音,这样就形成一个循环不息的录音过程。结束录音时就释放所waveInStop(m_hWaveIn); /停止录音waveInReset(m_hWaveIn); /清空内存块 在录音和放音的程序处理中,要特别注意两点。一个是分配的内存的大小和数量。内存的大小与IP电话中语音的连续性和延时性有直接关系,内存越大,则语音的连续性越好,但延时性越差,反之,内存越小,则语音的延时性越小,但连续性越差,所以要权衡利弊,取一个折衷量,这就需要反复实验。根据作者的实验,大约每个内存块录音的时间长度取0.1秒比较合适,具体的大小与采用的语音格式有关。内存的数量则与内存的大小和对每个内存的录音数据的处理时间长短有关,一定要保证在录音过程中,录音设备至少有一块内存可供录音,也就是说录满的内存要及时返回,使得循环能够顺利进行。由此可知,内存大,分配的数量就可以少,对每个内存的录音数据的处理时间短,分配的数量就可以少,反之,分配的数量就要多。当然可以分配足够多的数量,但是太多则耗费资源,降低了程序的效率。根据作者的实验,大约所有的内存块录音的时间长度和有0.5秒就足够了,也就是说,如果每个内存块录音时间长度为0.1秒,则可以分配5个内存块。程序中还有特别重要的一点是语音设备的Window消息的相应,通过语音设备发送的一系列消息,如MM_WIN_OPEN录音设备打开消息,MM_WIM_CLOSE录音设备关闭消息等,我们可以响应语音设备的打开,关闭,开始录音和放音,停止录音和放音,录音时一个内存块录满,放音时一个内存块放完等各种事件,来进行相关的处理。需要注意的是这些消息在VC的ClassWizard类工具的消息序列中是看不到的,需要手工编辑消息响应宏和代码。5.2.2 VC+实现语音数据的网络传输TCP/IP协议是网络上最通用的协议,本软件采用TCP/IP协议来进行数据语音的网络传输。CSocket类是Visual C+ 4.0新增加的一个类,它是对原来的Windows Socket API的封装,用它进行网络编程比用Windows Socket API要方便得多。建立网络的连接主要有如下三个步骤,一是在程序中加入Windows Sockets支持,二是以CSocket为基类构造两个新类CServerSocket和CMsgSocket。CServerSocket用来接收请求连接的申请,CMsgSocket用来传输数据。三是建立服务器方和客户机方的连接。下表显示了在服务器与客户机之间建立通信所需做的工作的顺序,具体的函数参数可查阅连机文档。服务器方首先构造一个CServerSocket类的对象,用来接收请求连接的申请,调用此对象的Listen成员函数,表示处于等待连接状态,等待客户机方发出申请连接(Connect)的消息,当接收到此消息后,CServerSocket类的OnAccept消息响应函数即会响应,此时再构造一个CMsgSocket类的对象(用来传输数据),然后调用CServerSocket类的Accept成员函数表示接受连接申请,若此函数返回真值,则表示连接成功。客户机方则只需构造一个CMsgSocket类的对象,调用此对象的Connect成员函数,申请连接即可。 服务器方 客户机方New CserverSocket,生成服务器对象new CmsgSocket,生成连接对象Create,创建Create,创建Listen, 处于监听状态Connect,申请连接New CmsgSocket,生成连接对象 Accept,接受连接Send,发送数据Send,发送数据Receive,接收数据Receive,接收数据按上述顺序建立连接后,服务器方和客户机方都调用CMsgSocket对象的Send函数来发送数据,当接收到数据时,CMsgSocket类的OnReceive消息响应函数即会响应,再调用Receive函数来接收数据,这样服务器方和客户机方就可以进行数据通信了。在程序中要注意网络消息的响应,如接收到数据,有客户申请连接,已连接上,对方已断开等等,与一般的消息响应函数不同,它已经集成在CSocket类的成员函数中,而不用消息响应宏。如在CServerSocket类中重载CSocket类的成员函数OnAccept,即可以处理申请连接的消息,在CMsgSocket类中重载CSocket类的成员函数OnReceive,即可以处理接收到数据的消息。重载CSocket类的成员函数OnClose函数,即可以处理对方网络已断开的消息。另外用CSocket类的成员函数GetPeerName可以得到对方的IP地址,在程序中可以保存下来,供以后连接使用,用户不必再重新输入。第六章 软件具体实现6.1软件的页面设计6.1.1 服务器端的界面设计图一6.1.2 客户端的界面设计图二6.2软件的运行方式软件服务器端的界面如上图一所示,运行本系统时必须首先运行服务器程序。软件客户端的界面如上图一所示,运行客户端程序后,可以与已知运行的服务器进行连接,连接方法:(1) 首先输入用户名,该用户名为客户端在服务器上注册的名称(可以任意输入)。(2) 选择用户的通信协议(推荐选择TCP/IP协议)。(3) 输入服务器的IP地址或服务器名称。(4) 点击连接按钮。如果服务器通过客户端的请求则表示客户端与服务器已经建立了连接。这是客户端的联系人里会出现与该服务器建立连接的所有客户端的名称。客户端可以通过选择联系人来请求与选择的联系人建立通话连接,当然,被选择的客户端也可以拒绝通话请求。如果被请求方同意了通话请求则表明了双方建立了连接。并可以进行通信了。任何一方在发送消息栏里输入的信息都会直接传到通信对象的接受消息栏中。当然客户端也可以选中“语音通信”,将自己的语音发送给对方,实现语音通信。通话完毕,双方都可以选择联系人中的“No one to talk”停止与对方交谈,类似与挂断电话。用户依据网络状况的好坏,可以采用压缩和不压缩的方式来传输语音(本程序还未实现)。在局域网内用不压缩的方式就可以达到很好的效果。实践证明,本软件在实际运行中稳定可靠,在局域网上音质和延迟都基本上达到了电话的效果。6.3软件的具体实现6.3.1处理客户端请求建立与服务器的连接 服务器收到客户端的连接请求,根据客户端传过来的协议和IP地址建立客户端和服务器间的连接,添加该客户信息进客户列表,更新所有客户端列表和服务器端列表,将服务器的socket设置成继续侦听状态。具体实现如下:根据此结构体typedef struct _VTMSG BYTE m_ucIdentity; / Identifies the message BYTE m_ucCmd; / message command BYTE m_ucMsgType; / The message type UINT m_lLength; / size of the message block BYTE m_pDataVT_MAX; / message data VTMSG, *LPVTMSG;中的m_ucCmd来确定用户传过来的是什么信息。如果接受客户端的数据不是客户端断开信息,即m_ucCmd!=VTCMD_SESSIONCLOSE,则分析客户端传过来数据的类型并处理该数据.当m_ucCmd= VTCMD_REGNAME,则说明客户端想要与服务器建立连接,服务器收到该信息,则根据客户端传过来的协议和IP地址建立与该客户端的连接。并且把该客户信息添加到客户列表,并将其状态设置成AVAILABLE。此时该客户端的信息便在客户下拉列表中显示出来,这样该客户便可以接受其它想与其聊天的任何客户端的请求,但只能接受一个客户的请求。6.3.2处理客户端向另一客户端发送连接请求服务器收到该客户端的请求后,服务器遍历所有客户列表,处理客户端的响应请求。具体实现方法如下:当此结构体typedef struct _VTMSG BYTE m_ucIdentity;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论