木马编程DIY之文本语音

86 篇文章 3 订阅
35 篇文章 0 订阅
 
                                   木马编程DIY之文本语音
                                                        冷风 德州科技职业学院
 
在黑防的第2期上天涯衰草(是电脑报上黑客营的老大吧呵呵)对“寿鼠”远程控制程序进行了介绍,其中有一个
功能就是“跟对方讲英语”感觉很有意思,就试着自己做了一个发现也不是太难,效果如图1所示
程序在VC6.0+WIN2000下编写分为服务端(SDK)和客户端两个文件,在其它机器的运行服务端后,就可以通过客户端让它“说话”了,如果目标
地址为空的话,会在自己的电脑上朗读。
 
 
 
关于文本语音
 
寿鼠的朗读功能就是通过文本语音实现的,文本语音又称为TTS(Text-to-Speech)它的作用就是把文本转化为语音,如果我们想
开发这种程序,需要使用软提供的软件开发包Microsoft Speech SDK,目前使用最为广泛的版本是5.1,这个包大小在65M左右在
天空,军华都可以下载到,它本身带有十分详细的开发资料,和可执行程序如图2图3所示,参考帮助文档提供的例子我们可以
很方便的做出自己的程序了。
 
 
准备工作
 
在开始前应该把Microsoft Speech SDK安装好,装好后进入安装目录把INCLUDE和LIB目录中的头文件与库文件复制到VC的开发目录里面
我这里是C:/Microsoft Visual Studio/VC98/Include跟LIB目录,当然你也可以在VC中设置路径(我喜欢直接复制过去)现在就可
以编写程序了
 
服务端编写
 
 
服务端运行后就一直在5555端口监听,收到数据就读出来,实现代码如下
 
 
#include  < sapi.h >            // TTS所需要的头文件
#include  < windows.h >
#include 
< winsock.h >
#pragma  comment (lib,"ws2_32")  // 加载库函数
 
const   int  buffer_len = 2048 ;
 
int  APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     
int        nCmdShow)
{
 
       WSADATA wsadata;
       SOCKET server;
       SOCKET client;
       SOCKADDR_IN serveraddr;
       SOCKADDR_IN clientaddr;
       
int     port = 5555 ;
       
char  buffer[buffer_len];
       WCHAR wbuffer[buffer_len];
 
       memset(wbuffer,
0 , sizeof (WCHAR) * buffer_len);
       memset( buffer,
0 sizeof ( char ) * buffer_len);
 
 
       WORD ver
= MAKEWORD( 2 , 2 );                                              // 判断winsock版本
       WSAStartup(ver, & wsadata);                                     // 初始SOCKET
 
       server
= socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
 
       serveraddr.sin_family
= AF_INET;
       serveraddr.sin_port
= htons(port);
       serveraddr.sin_addr.S_un.S_addr
= htonl(INADDR_ANY);
 
       bind(server,(SOCKADDR
* ) & serveraddr, sizeof (serveraddr));
       
       listen(server,
5 );
 
       
int  len = sizeof (clientaddr);
 
       
while ( 1 ) // 循环接受连接
       {
              client
= accept(server,(sockaddr  * ) & clientaddr, & len);
 
              
while ( 1 ) // 循环接受数据
              {
                     
if (recv(client,buffer,buffer_len, 0 ) != 0 ) // 有数据则播放
                     {
                            memset(wbuffer,
0 , sizeof (WCHAR) * buffer_len);
                            
// 必须先转换成宽字符
                            MultiByteToWideChar( CP_ACP,
                                                                MB_PRECOMPOSED,               
//  character-type options
                                                                buffer,                                //  address of string to map
                                                                buffer_len,                          //  number of bytes in string
                                                                wbuffer,                                    //  address of wide-character buffer
                                                                buffer_len                                  //  size of buffer
                             );      
 
                            
                            memset( buffer,
0 sizeof ( char ) * buffer_len);
                                    
                            ISpVoice 
*  pVoice  =  NULL;
 
                            
if  (FAILED(CoInitialize(NULL))) // 处始化COM接口
 
                            {
                                   MessageBox(NULL,
" ERROR " , " Error to intiliaze COM " , 0 );
                            }
                           
// 获取ISpVoice接口
                            HRESULT hr  =  CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_ALL, IID_ISpVoice, ( void   ** ) & pVoice);
 
                            
if ( SUCCEEDED( hr ) )
                            {   
                                   hr 
=  pVoice -> Speak(wbuffer,  0 , NULL);  // 开始朗读
                                   pVoice -> Release(); // 完成后释放声音对象
                                   pVoice  =  NULL;
                            }
 
                            CoUninitialize();
// 释放
                     }
                     
else
                            
break ; // 接受数据为0退出
              }
       }
 
       closesocket(server);
       closesocket(client);
       WSACleanup();
 
       
return   0 ;
}
 
实现代码挺简单的,需要注意的是在
pVoice->Speak(const WCHAR *pwcs,DWORD dwFlags,ULONG *pulStreamNumber);中pwcs是WCHAR类型的也就是Unicode编码
所以从网络收到数据后要进行Unicode转换,编码转换可以用MultiByteToWideChar API来实现,这是一个很好用的API看看上文
的代码就会用了。
 
客户端实现
 
客户端实现同样很简单,所以我就不再浪费感情了呵呵
 
void  CMyDlg::OnOK() 
{
       UpdateData();
 
       
if(m_addr.IsEmpty())//地址为空则本地播放
       {
              
//实现代码与服务端相差无几            
       }

       
else//把数据发送至目标
       {
              WSADATA wsadata;
              SOCKET client;
              SOCKADDR_IN serveraddr;
              
int port=5555;
 
              WORD ver
=MAKEWORD(2,2);                 //判断winsock版本
              WSAStartup(ver,&wsadata);        //初始SOCKET
 
              client
=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
 
              serveraddr.sin_family
=AF_INET;
              serveraddr.sin_port
=htons(port);
              serveraddr.sin_addr.S_un.S_addr
=inet_addr(m_addr.LockBuffer());//m_addr为接受地址的文本控件
 
              connect(client,(SOCKADDR
*)&serveraddr,sizeof(serveraddr));
 
              send(client,m_text.LockBuffer(),m_text.GetLength(),
0);//m_text为接受内容的文本控件
 
              closesocket(client);
              WSACleanup();
       }

}

 
 
需要的话,还可以扩充一下,让它读中文日文什么的,不过你还得专门去下载发声补丁......而且也可以指定男音或女音
朗读不过我感觉女音比较好听嘿嘿,本文实现的功能比较简单,如果想编写功能强大的程序还是请参考Microsoft Speech SDK
的帮助文档,
 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值