logo资料库

基于MFC的远程屏幕传输.pdf

第1页 / 共4页
第2页 / 共4页
第3页 / 共4页
第4页 / 共4页
资料共4页,全文预览结束
基于 MFC 的远程屏幕传输 王 刚 青岛大学电子学系,266071 (Qindao University,Department of Electronic ,266071) 摘要:本文以 VC++6.0 为开发环境,实现了纯软件网络教室服务器程序和客户端程序。服务器程序 实时采集屏幕图象,并对其应用高效压缩算法,使用 CAsyncSocket 套接字类,在局域网上实现实时 广播,客户端程序实时接收、解压并显示图象。经实验可以达到每秒 10 帧速度,基本满足机房同步 教学需要。 关键词:局域网;TCP/IP 协议;套接字;数据包 分类号 TP393 1.引言 多媒体网络教室在比传统意义上的黑板加粉笔的教学手段具有明显优势,也不同于一台投影机加 一台计算机的演播方式。它可以更有效地加强教师的“教”与学生的“学”之间的信息互动与资源共 享。可以实现个别学习和协同学习相结合的多种模式,实现了课堂教学的变革。加强了教学过程中教 师的主导作用,激发了学生主体的学习兴趣。网络教学不再是一个人的封闭学习环境,而是一个开放 的系统,实现双向教学,采取有提问、有反馈、有交流的教育方法。 以往都采用纯硬件或软硬结合方式构建,纯硬件方式存在成本较高、安装繁杂、不可升级和维护 困难等缺点。软硬件结合方式是在硬件网络教室的基础上再铺设多媒体网络,并利用软件进行教学控 制和数据的传输。它除了纯硬件方式的缺点外,更加重了系统的成本。当然这两种方式也有实时传输、 计算机配置无须太高、不依赖操作系统等优点。但是随着计算机性能和网络速度的进一步提高,这些 优点将越来越不明显。 如今,10/100M 网卡已经象声卡和光驱一样成为计算机的基本配置,不少纯 软件系统可以在 10M 局域网上直接运行。纯软件网络教室具有成本低、安装维护简单、开放性、兼 容性好、多向互动性、容易升级和不受教室的物理空间限制等优点。虽然在实时画面广播上还不如硬 件,但是对于教学来说,每秒 5-10 帧的速度已经可以满足使用(VCD 广播则可达到 24 帧以上), 而且随着计算机及网络性能的提高,速度将会不断提升。 一般网络教室都具备同屏传输、声音传输、远程控制、远程监视、黑屏肃静、分组讨论等功能。 同屏传输是最根本和最重要的功能之一。 2.传输原理 随着计算机网络化的深入,计算机网络编程在程序设计的过程中变得日益重要。许多文章都曾 经介绍过用 VC++进行 Socket 编程的方法。但由于都是直接利用动态连接库 wsock32.dll 进行操作, 实现比较繁琐。其实,VC++的 MFC 类库中提供了 CAsyncSocket 这样一个套接字类,用它来实现Socket 编程,是非常方便的。 教师机作为服务器,通过教师机程序捕获屏幕图象,然后分割成许多数据包,采用快速压缩算法 压缩后通过网络发送给学生机。学生机从网络上接收数据包,解压后重新组织起来,显示到屏幕上。 因为发出的数据包由许多台计算机同时接收,所以采用广播数据报方式。 发送程序先要在 VC++下用 MFC AppWizard 建立一个基于 Dialog 的项目,使用 Windows Socket 支持。要截取屏幕图像信息,可先用桌面窗口指针定义一个 CWindowDC 类对象 ddc,再定义一个CDC 类的对象 wdc 和一个 CBitmap 类对象 bmp1,然后用 wdc 的成员函数建立与 ddc 兼容的设备上下文, 用 bmp1 的成员函数建立一定尺寸的兼容位图,接着用wdc 的成员函数 SelectObject 将位图对象 bmp1 选择为操作目标,准备捕获屏幕,使用 wdc 的成员函数 BitBlt 将 ddc 里的屏幕图像截取到其中 bmp1 对象内,用 bmp1 的成员函数 GetBitmapBits 将位图数据信息保存到指定的内存中,把这些数据发送 到学生机上即可再现图像。还要把鼠标指针也显示出来,可用函数获取鼠标位置,将其描述在保存的 图像信息中。 为将数据快速发送出去,须使用 CAsyncSocket 的异步通讯方式。异步方式在命令教师机将数据 _______________________________________________________________________________www.paper.edu.cn
包发送出去后就立即返回,不用等数据发完,当数据发送完后计算机能自动产生一个消息,通知程序 可以发送下一个数据包。该方式要求用户必须自己用 CAsyncSocket 类派生出一个新类,重载 OnSend 函数,以便响应 FD_WRITE 网络事件,该事件在数据包已经全部从网络发送出去后产生,并让教师 机自动执行 OnSend 函数。因此该函数中含有发送下一个数据包的命令。为了让学生机收到数据包后 知道这是第几个数据报,在数据包首用一个数字编号,这样可避免出现像素块定位错误。每次发送数 据前采用 JPEG 压缩算法压缩数据,以提高传送速度。当一屏数据发送完后,就再捕获下一屏数据发 送。 3.传输实现 发送程序: (设项目名为 Netss,以 16 位增强色为例)用 MFC AppWizard 建立基于 dialog 的目标 工作空间后,在 CNetssDlg 派生类中加入以下程序,其中 OnCreate 的函数框架用 ClassWizard 响应 WM_CREATE 消息生成,里边做一些初始化操作。 int i=0,ii,iii,xx,yy,b=1,pa,bl=3840,eee=8192; int wx=800,wy=600; //屏幕分辨率 int eees=5; //发送频率 short aa[1200000]; //存放截取屏幕信息的缓冲区,要根据屏幕分辨率调整大小 LPVOID pbit0=&aa[1000]; CDC wdc; CBitmap bmp1; CDC* pdc; char frame[5000]; //发送缓冲区 POINT pp;LPPOINT ppp=&pp; //用于获取鼠标位置的变量 void* pbuf=(void*)(&frame[0]); int *paa=(int*)pbuf; char *pf; short *pfi; class mysocket:public CAsyncSocket {public:void OnSend(int nErrorCode) {if(pa>wx*wy) //如果发送完一屏信息,则截取下一屏信息 {pa=1000;wdc.BitBlt(0,0,wx,wy,pdc,0,0,SRCCOPY);//把桌面图像复制到 wdc 的 bmp1 中 bmp1.GetBitmapBits(wx*wy*2,pbit0); //获取图像信息 GetCursorPos(ppp); //获取鼠标位置 xx=ppp->x; yy=ppp->y; for(ii=0;ii<10&&xx>i); else if(aa[pa]==aa[pa-wx]) *pf=*pf|(0x80>>i); else if(aa[pa]==aa[pa-wx-1]) *pf=*pf|(0xc0>>i); else {*pfi=aa[pa]; pfi++; } pa++; } pf=(char*)pfi; pfi=(short*)(pf+1); } 中国科技论文在线_______________________________________________________________________________www.paper.edu.cn
CAsyncSocket::SendTo(pbuf,bl,1050,NULL,0); //把该段信息发送出去,发送 bl=3840 字节 if(eees>0) //控制发送频率 {eees--; CAsyncSocket::AsyncSelect(FD_WRITE); //允许对象 socks 继续响应 FD_WRITE 事件 } } }; mysocket socks; int CNetssDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialog::OnCreate(lpCreateStruct) == -1) return -1; socks.Create(1050,SOCK_DGRAM,FD_WRITE,NULL); //建立数据报 Socket,端口号 1050 socks.SetSockOpt(SO_BROADCAST,&b,sizeof(BOOL),SOL_SOCKET); //选择广播数据报 socks.SetSockOpt(SO_DONTROUTE,&b,sizeof(BOOL),SOL_SOCKET); socks.SetSockOpt(SO_SNDBUF,&eee,sizeof(int),SOL_SOCKET); //设置发送缓冲区长度 eee socks.AsyncSelect(FD_WRITE); //允许对象 socks 响应 FD_WRITE 事件 static CWindowDC ddc(GetDesktopWindow()); pdc=&ddc; //引用桌面窗口指针定义对象 ddc wdc.CreateCompatibleDC(pdc); //建立与 ddc 兼容的 device context, bmp1.CreateCompatibleBitmap(pdc,wx,wy); //建立与 ddc 兼容的位图 wdc.SelectObject(&bmp1); //选择 bmp1 pa=1000; //数据从缓冲区第 1000 个元素开始存放 SetTimer(1,5,NULL); //初始化计时器 return 0; } void CNetssDlg::OnTimer(UINT nIDEvent) {eees=5; //用计时器控制发送频率 socks.AsyncSelect(FD_WRITE); CDialog::OnTimer(nIDEvent); } 接收程序则要在 C++下用 MFC AppWizard 建立一个单文档项目,其他处理方法与发送程序相似, 但要注意此时要响应的是 FD_READ 事件,该事件在网络上有数据报到达时发生,因此要重写的是 OnReceive 函数,该函数中要有从网络接收数据包的命令,并能根据数据包最后的数字编号判断这是 第几个数据报,将收到的信息放到合适的地方。 当把保存一屏信息的数据报全部收完后,就可用来 把图像再现到屏幕上。一般希望再现的图像显示在用户窗口中,因此引用用户窗口指针定义CClientDC 类对象 sdc,代替发送程序中的 ddc,再现时的处理与发送时相反,把从网络上收到的数据用位图bmp2 的成员函数 SetBitmapBits 复制到位图 bmp2 中,再用 sdc 的成员函数 BitBlt 把 bmp2 中的图像显示在 用户窗口中。 接收程序: (设项目名为 Netcc)在 CNetccView 派生类中加入以下程序,其中 OnCreate 函数框架用 ClassWizard 响应 WM_CREATE 消息生成,里边做一些初始化操作。 int i=0,bl=3840,wx=800,wy=600; short aa[1200000],ff,*pfi; LPVOID pbit0=&aa[1000]; DWORD dw=0; UINT nport; char frame[5000],*pf; void* pbuf=(void*)(&frame[0]); int *paa=(int*)pbuf; CDC wdc;CBitmap bmp2; CDC* pdc; CString ip_no; UINT port_no; class mysocket:public CSocket {public: void OnReceive(int nErrorCode) {CSocket::Receive(pbuf,bl,0); //接收数据报 pf=&frame[4]; pfi=(short*)(pf+1); 中国科技论文在线_______________________________________________________________________________www.paper.edu.cn
for(;pf<&frame[1836];) {for(i=0;i<8;i=i+2) //JPEG 解压缩 { ff=(*pf)&(0xc0>>i); if(ff==(0x40>>i)) {aa[*paa]=aa[(*paa)-1]; } else if(ff==(0x80>>i)) {aa[*paa]=aa[(*paa)-wx]; } else if(ff==(0xc0>>i)) {aa[*paa]=aa[(*paa)-wx-1]; } else {aa[*paa]=*pfi; pfi++; } (*paa)++; } pf=(char*)pfi; pfi=(short*)(pf+1); } if(*paa>wx*wy) {bmp2.SetBitmapBits(wx*wy*2,pbit0); //在窗口显示收到的屏幕信息 pdc->BitBlt(0,0,wx,wy,&wdc,0,0,SRCCOPY); } } }; mysocket sockc; int CNetccView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; sockc.Create(1050,SOCK_DGRAM,NULL); nport=1050; static CClientDC ddc(this); pdc=&ddc; //引用应用程序窗口指针定义对象 ddc wdc.CreateCompatibleDC(pdc); bmp2.CreateCompatibleBitmap(pdc,wx,wy); wdc.SelectObject(&bmp2); *paa=1000; return 0; } 4.结论 该程序在 VC++6.0 下编译运行通过,运行环境操作系统要求 WIN95 以上,网络必须安装 TCP/IP 协议。使用时要注意教师机和学生机必须使用相同的颜色显示模式,建议使用 16 位增强色模式否则 显示不正常。教师机只需要运行发送程序,学生机运行接收程序。 以 640*480 分辨率为例,当采用 16 位增强色时在 10M 网络上每秒可发送 4 到 5 帧图像,在 100Mbps 网络上每秒可发送 20 帧以上图像, 可满足多媒体视频传输的要求。 参考文献 [1]李杰.关于 Windows 套接字的研究[J].安徽:安庆师范学院学报(自然科学版).2002,8(4).-86-87. [2]Anthony Jones,Jim Ohluncl,Windows 网络编程技术[M].北京:机械工业出版社,2001. [3]胡静,古乐野. 使用 CAsyncSocket 类实现异步网络通信[J].成都:计算机应用.2002 ,22(7).-108-109,112. [4]甘辉,李立.应用 WINSOCKET 实现远程抓屏幕技术[J]. 宜春:宜春学院学报.2002 ,24(4).-47-49. [5]李丽,蒋洪睿.基于 MFC 封装的 Windows 通信 API 的研究[J].北京:计算机系统应用. 1999(10).-27-29 The Remote Same-screen Transmission Based on MFC WANG Gang Qindao University,Department of Electronic ,266071 Abstract: VC++6.0 is used to develope the server program and client program of e-class. Server program captures the screen realtime and applys a efficiency compression arithmetic. The CasyncSocket class is used to realize real time broadcast.The client program receives,decompresses and display the image.It is tested to reach 10fps. It can basiclly satisfy the need of synchronization teaching in computer classroom. Keyword:LAN;TCP/IP protocol;Socket;data package 作者简介:王刚,讲师,1971 年 5 月-.1995 年毕业于青岛大学自动化系.现攻读青岛大学计算机科学 与技术硕士学位.主要从事计算机应用软件开发及教学科研工作. 联系电话:5953153 转 3 手机 13001686180 宅电 4964135 email: qdu_wg@sina.com 中国科技论文在线_______________________________________________________________________________www.paper.edu.cn
分享到:
收藏