远程控制UDP版

一、主要技术--按照客户端控制服务器的实现来讲

UDP版和TCP版的主要区别是数据发送方式不同,tcp通过连接,通过流来发送和接受数据,非常可靠,UDP是

发送数据包和接受数据包的过程,而且发送的数据包可能丢失,数据包的大小也有限制。也就是字节数组的大小有限制。

我的屏幕截图下来有4M,不能够一次性发在字节数组中发送,我的实现办法是,先将对象序列化写入文件,然后将文件分成一百分发送出去,客户端接受的时候也将接收的字节写入文件,然后用对象输入流读取,就相当于对象的序列化过程,和文件复制。

二、主要实现步奏都是一样的可以参考tcp的实现,下面是发送数据和接受数据的过程。

1、服务器发送数据包代码

注意事项由于可能丢包,所以每发送一张图片也就是一个对象时,先发送”开始标记“,然后再发送分隔的100分字节数组,客户端在接收到”开始“字节数组之后开始接受,接受100份后边开始按照对象流读取图片对象,如果对象读取不成功,说明这100份字节数组出现了错误,不是一个完整的对象的字节数组,将其丢弃重新开始接受,直到对象成功读取才将去画在客户端的面板上。

public void run() {

  
   Robot robot;
   try {
    robot = new Robot();
    
    while (true) {
     System.out.println("开始");
     //得到屏幕大小,由于在远程控制中,可能改变屏幕分辨率,所以要不断获取
     Toolkit tool = Toolkit.getDefaultToolkit();
     //
     Dimension dimension= tool.getScreenSize();
     Point point = new Point(0,0);
     
     //创建一个矩形用于指定截屏区域
     Rectangle screenRect = new Rectangle(point,dimension);
     
     // 不断地截屏,然后发给客户端
     BufferedImage bimg = robot.createScreenCapture(screenRect);
     
     //BufferedImage没有实现接口,所以不能被实例化,所以将其转成imageicon
     ImageIcon img = new ImageIcon(bimg);
  
//***********************************************************************     、
     //先把对象写入文件,再把文件转成字节数组发出去,对方接受文件,再按对象读取
     File file = new File("d:/jietu.png");
     FileOutputStream fos  =  new FileOutputStream(file);
     
     BufferedOutputStream bos  = new BufferedOutputStream(fos); 
 
     //包装成对象流
     ObjectOutputStream os = new ObjectOutputStream(bos);
     //将对象写入文件
     os.writeObject(img);
     os.flush();
     
     //*******************
     //将文件转成字节流发出去
     byte[] b = new byte[(int) file.length()];
     FileInputStream fis = new FileInputStream(file);
     fis.read(b);
     
     System.out.println(b.length);
     int skp = (int) (file.length()/100);
     int len =skp;
     //先发送一个头,表示这个一张数据的开始
     byte[] b0 = "开始".getBytes();
     //把开始标记发出去
     DatagramPacket dp2 = new DatagramPacket(b0,b0.length, sentaddress);
     socket.send(dp2);
     //把文件大小用字节数组发出去
     byte[]  filelength=(file.length()+"").getBytes();
     
     //将数组复制到指定长度为20的数组,不够的补0
     byte[] bl=Arrays.copyOf(filelength, 20);
     System.out.println("数组大小为"+file.length());
     
     
     DatagramPacket dp3 = new DatagramPacket(bl,bl.length, sentaddress);
     socket.send(dp3);
     
     for(int i =0;i<100;i++){
      if(i==99){
       //最后剩下的长度
       len=b.length-99*skp;
       System.out.println(i);
       System.out.println(len);
      }
      System.out.println(i);
      System.out.println(len);
       dp2 = new DatagramPacket(b, i*skp,len, sentaddress);
      socket.send(dp2);
     Thread.sleep(10);
     
     }
   
    }
    
   } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
 
   
 }

三、客户端接受到数据之后,先将其写入文件,然后再用对象流读取,读取成功才将起画在面板(这里没有判断是否成功读取对象)

 while (true) {
   File file0 = new File("e:/jietu.png");
   //如果有原来的截图就将其删掉
   if(file0.exists()){
    file0.delete();
   }
   try {
   
    File file = new File("e:/jietu.png");
    FileOutputStream fos = new FileOutputStream(file);
    byte[] b0 = new byte[4];
    DatagramPacket dp0 = new DatagramPacket(b0, b0.length);

    socket.receive(dp0);
    // 如果是头就开始接受图片

    if ("开始".equals((new String(b0)).trim())) {
     int sum = 0;
     byte[] blength = new byte[20];
     DatagramPacket dplength = new DatagramPacket(blength,
       blength.length);
     socket.receive(dplength);
     int length = Integer.parseInt((new String(blength)).trim());
     System.out.println("大小为%%%%"+length);
     int length1=length/100;
     int length2=length-length1*99;
     for (int i = 0; i < 100; i++) {
      if (i == 99) {
       byte[] buf = new byte[length2];
       DatagramPacket dp2 = new DatagramPacket(buf,
         buf.length);
       sum++;
       socket.receive(dp2);
       fos.write(buf);
       fos.flush();
       

      } else {
       byte[] buf = new byte[length1];
       DatagramPacket dp2 = new DatagramPacket(buf,
         buf.length);
       sum++;
       socket.receive(dp2);
       System.out.println(i);
       fos.write(buf);
       fos.flush();
      }

     }
     System.out.println("%%%%%" + file.length());
     fos.close();
     //如果sum不等于100,说明没有完成接受到图片对象,有丢失,则不能将对象完整读取出来,所以直接放弃,只有完整读取才能将其画出来
     if(sum==100){

     FileInputStream fis = new FileInputStream(file);
     BufferedInputStream bos = new BufferedInputStream(fis);
     ObjectInputStream ois = new ObjectInputStream(bos);

     ImageIcon img= (ImageIcon) ois.readObject();

     

     ois.close();
     bos.close();
     fis.close();

     Graphics g = panel.getGraphics();
     g.drawImage(img.getImage(), 0, 0, null);
     System.out.println(">>>>>>>>>>>>>");
     file.exists();
     file.delete();
     }

    }

   } catch (Exception e) {
    // TODO Auto-generated catch block
    
    e.printStackTrace();
   }

猜你喜欢

转载自376798041.iteye.com/blog/2126742