远程控制(1)


先说一下上次的类似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



你可能感兴趣的:(远程控制(1))