• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Kevin Wu's Corner
暂时停一停
博客园    首页       联系   管理    订阅  订阅

远程控制(1)

一个类似qq远程协助的东西 文件传送基本流程 获取数据--设置缓冲区--定义数据结构--封包--发送

先说一下上次的类似qq截图的那个东西,实在有够菜的,见笑了

那么现在我开始做的是一个类似qq远程协助的东西,全屏截图压缩发送这个在所难免的了。对于用Windows Hook进行窗口事件拦截截图这个功能我还是卡在哪里,每次调试都搞到explorer关闭,有次还差点死机了。。。。。。

所以我还是先做传输和控制的部分了,那么就开始吧

一.图片发送,我很蠢的选择了udp作为图片传送方式,最后搞到挺麻烦的(数据整合)

首先我们先截图(废话),同时保存在一个内存流中,就是方便呀

private MemoryStream ImageStream = new MemoryStream();
ScreenImage.Save(ImageStream, System.Drawing.Imaging.ImageFormat.Jpeg);

ScreenImage是内存中截屏后的图片,将它保存到ImageStream这个内存流中,我有想过这是不是多此一举,同是内存里面的东西,何必要转来转去呢?希望高手可以稍微说说这个问题。

下面就到了封包的环节了,这里就需要定义自己的数据包结构了,我做得简单点,请看下面
        struct ImageBlock
        {
            
public int Num;
            
public Byte[] Content;
            
public int ContentLen;

            
public ImageBlock(int Num, int Length, Byte[] Content)
            {
                
this.Num = Num;
                
this.Content = Content;
                
this.ContentLen = Length;
            }

            
public ImageBlock(int Num)
            {
                
this.Num = Num;
                ContentLen 
= 2040;
                Content 
= new Byte[2040];
            }

            
public Byte[] ToBytes(out int length)
            {
                Byte[] one 
= BitConverter.GetBytes(Num); 
                Byte[] two 
= BitConverter.GetBytes(ContentLen);
                length 
= one.Length + Content.Length + two.Length;
                Byte[] Bytes
=new Byte[length];
                one.CopyTo(Bytes, 
0);
                Content.CopyTo(Bytes, one.Length);
                two.CopyTo(Bytes, length
-two.Length);
                
return Bytes;
            }
        }

因为我将缓冲区设定为2048,为什么?我不知道,老师说的。那么我就将包大小设成2048
4(int)+2040(byte[])+4(int)=2048
这个是最大值哦,可以少于这个值,看ContentLen的值决定最后包的大小,一般情况下都是2048
最后一个ToBytes()函数将整个包转成Byte[],因为发送是以字节为单位(说错了别扔鸡蛋)

好了,图片包的数据结构做好了,那么开始封包,无非就是循环循环再循环,ImageStream里面的内容封装到ImageBlock的Content里面,同时给包加上包号(为了客户端接收后按顺序组织)和内容长度。下面是个简单的循环

MemoryStream imagestream = new MemoryStream();
ScreenImage.Save(imagestream, System.Drawing.Imaging.ImageFormat.Jpeg);
long length = imagestream.Length;
int ret = 0;
imagestream.Seek(
0, SeekOrigin.Begin);
int begin = 0;
int num = 0;
while (length > 0)
{

    ImageBlock block = new ImageBlock(num);
    block.ContentLen 
= imagestream.Read(block.Content, 0, 2040);
    length 
-= block.ContentLen;
    
if (block.ContentLen < 2040)
        block.Num 
= -1; //读到内存流最后了
    
else
    {
        block.Num 
= num;
        num
++;
    }
    
int sendlen;
    //发送
    ret
=udpClient.Send(block.ToBytes(out sendlen), sendlen, ClientPoint);
    Console.WriteLine(block.ContentLen.ToString());
    
if (ret < sendlen)
    {
        //假如发送大小不等于包大小,重发
        num
--;
        imagestream.Seek(-2040, SeekOrigin.Current);
    }
}

嗯,到这里,基本就完成了图片发送了,忘记说了,发送记得要用一个线程独立发送,不然的话,程序就卡在那里了。完整代码我就不给出了,因为我还在做,我自己都觉得实在够乱的,整理麻烦

这里说了文件传送基本流程
获取数据-->设置缓冲区-->定义数据结构-->封包-->发送

希望有高手可以给我指点指点,能让我改进一下,我还是初学者

友情提示:
如需转载本文,请遵守"本站协议"并加入下面声明 且注明原文链接。
作者:kevin wu
来源:kevin wu's corner



by Kevin wu  
posted @ 2006-12-31 10:22  Kevin Wu  阅读(1424)  评论(1)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3