二.接收

上面已经讲到如何将数据包发送出去,剩下的就是接收,和控制
既然发送端是用upd发送,那么接收端当然也是用udp接收(好多废话哦)

简单点,用个循环将接收到的包按包号写入内存,然后在内存中读取数据,还原图片,具体步骤如下:

接收包-->按包号计算偏移-->接收到最后一个包-->写入-->还原图片-->显示
          |          |
      写入内存(循环)     

很简单是吧,假如要考虑到其他的问题的话,那么就会复杂一点,上面所有动作将放在一个单独线程执行

  (1)接收包
     
   IPEndPoint hostPoint = new IPEndPoint(IPAddress.Any, 0);
远程控制(2)Byte[] recv = ReceClient.Receive(ref hostPoint);

UdpClient的Receive是总是阻塞的,直到有数据包的到来,接受到字节后,还要进行分解,上面漏了一步,根据我们发包的内容,我们可以知道包内各个位置放着的是什么数据
0-3     包号
4-?     包内容
?-end 包内容长度

为什么用?呢,这个就关系到这个数据包的设计问题了.现在想想真的是一大失败.由于包内容的长度不一定是固定的,包内容长度用来描述包内容长度,在读取的时候就有点麻烦,如下
远程控制(2)for (int i = 0; i < 4; i++)
}

每次都要用包长度-4来获取包内容长度.假如开始我们的数据包设置成
远程控制(2)        struct ImageBlock
           
                public int ContentLen;
远程控制(2)            
public Byte[] Content;
远程控制(2)        }

那么就会好很多
0-3     包号
4-7     包内容长度
7-end 包内容

获取包号和长度之后,就可以写入内存中相应的位置了.
计算?    
远程控制(2)MemoryStream iStream = new MemoryStream();
远程控制(2)iStream.Position 
= block.Num * 2040;
   iStream.Write(block.Content, 0, block.ContentLen);

一般来说,只要不是最后一个包的话,每包数据量都是2040,所以......虽然我觉得有点汗,但是还是这样处理算了.同时还有一个问题,udp包按顺序发,但不一定是按顺序接收.先看看这里
远程控制(2)if (block.Num == -1)
 }

记得上次发包的时候将最后一个包包号写成-1 吧,假如这个包在其他包接收到之前就已经被接收,那么内存中的数据就会立刻被转成图片,并且显示.那么后来来到的那些包呢(我指同一张图片的),没有丢,也接收了,不过已经失去了意义.虽然在局域网里这个情况不是很明显,但是在internet上的话,就很大问题了.所以用udp还是有那么一点痛苦.所以,我们可以改用tcp了(面向连接),顺序就不会搞错,耗点资源也值得.同时也有其他的一些方法,用udp也能够完成类似tcp的任务,我还没弄,只是知道有,就不介绍了

到这里,一张图片的接收就完成了远程控制(2),怎么显示?对哦,还没说.....我用的是panel.  ImagePanel.BackgroundImage.很简单吧.在显示之前,要设置好panel大小,意思就是获得对方屏幕的大小,怎么做就不说了,和上面说的一样.传~~~~
获取屏幕大小的方法:
Screen.AllScreens[0].Bounds.Size;
假如对方有多个显示器的话......那...一般都是一个啦.....0就是第一个

好,有画面显示了.下面就开始控制

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



相关文章:

  • 2021-04-28
  • 2022-01-06
  • 2021-06-11
  • 2021-08-22
  • 2021-05-16
  • 2021-09-12
  • 2021-07-24
  • 2021-11-08
猜你喜欢
  • 2021-06-03
  • 2021-07-28
  • 2022-02-09
  • 2021-12-05
  • 2021-05-17
相关资源
相似解决方案