基于UDP的网络通信之屏幕共享(1)


基于UDP的网络通信之屏幕共享

UDP是一种用途广泛的网络传输协议,发送方只管发送数据出去,而不管是否能够送达。

应用范围:有时候因为网络问题,接收方可能会丢失部分数据,但是并不影响程序的功能。例如视频直播的时候有一些数据丢失了,最多就是卡顿一下,并不会造成功能很大的影响。

对于发送者而言,需要有一个发送者的地址与端口,也需要知道要发到哪个地址的哪个端口。同时还需要一个socket传送数据。

在这里,可以将他们形象的比喻成邮政系统。

发送者就是寄件人,接收者就是收件人,而传递着就是邮递员。

  1. // 创建一个发送者发件人)   
  2. SocketAddress sender = new InetSocketAddress("127.0.0.1", 912);   
  3. // 创建一个接收者收件人)   
  4. SocketAddress receiver = new InetSocketAddress("127.0.0.1", 913);   
  5. // 创建一个传递者邮递员)   
  6. DatagramSocket socket = new DatagramSocket(sender);   

而对于寄件人而言,他需要将要寄的东西用一个包装装好,也就是包裹一样。然后再交给邮递员送出去。

  1. byte[] msg="Hello!".getBytes();   
  2. DatagramPacket m = new DatagramPacket(msg, msg.length, receiver);   
  3. socket.send(m);   

对于接收者而言,他需要知道去哪里取数据,邮递员是谁,收到了一个包裹。

  1. // 创建接收对象收件人)   
  2. SocketAddress receiver = new InetSocketAddress("127.0.0.1", 913);   
  3. // 得到消息接收的socket邮递员)   
  4. DatagramSocket socket = new DatagramSocket(receiver);   
  5. // 定义好包裹   
  6. DatagramPacket data = new DatagramPacket(buf, buf.length);   
  7. // 用socket将数据包裹接收进来   
  8. socket.receive(data);    

这其中就需要定义一些协议。

UDP出了上述一对一共享,还可以以组播的方式共享数据,即一对多。

这里以简单的屏幕分享为例

首先,要明确我们的目的是需要将某台计算机的屏幕分享给其他人。

也就是将计算机屏幕截图,再使用局域网组播。

由于每次发送的数组不能过大,所以截取屏幕得到的图片需要分多次发送出去,等客户端接收到了再拼成原图。所以需要一个信息头来保存图片的基本信息以便于客户端收到之后能顺利拼回原图。

关键在于如何定义这个信息头,在接收方我们需要知道发送端传给我们的图片是分多少次发送过来的,也要知道总共有多少个字节,还要判断是不是因为网络原因有部分数据被丢弃了,那样的话自然就无法还原数据了。

在这里,我采用的方法是:

信息头定义如下:

第一个字节为类型,暂时用0表示图片

第二个字节为数据组数,意思是这张图片分成了多少次发出去,在客户端需要收到多少才能pin回来

第三个字节为随机的一个记号,用来告诉客户端是否数据丢失了。如果有数据丢失,

则应该丢弃相关的所有数据,不能拼回原图,则跳过这一帧。

第四个字节为实际要传输的数据长度的位数。比如实际上是1234byte,则这个值是4

接下来的n个为长度信息,比如:data[4] = 1;data[5] = 2;data[6] = 3;这就表示长度为1234

每一次都发10000个实际字节数据

加上10个左右的头部信息。所以每个数组长度都是10010

客户端接收到消息之后,就要判断是不是有数据丢失。没有的话就会拼回原图并显示

接收到了这次的数据之后,如果发现前一组丢了部分数据,那么就要将前一组数据全部清空,然后继续接收


相关内容