怎么实现屏幕截图和远程同步(意思就是我发个图给客户端,它能显示在屏幕上)  大侠们 有人做过么。。讲讲心得

解决方案 »

  1.   

    1: 用 Robot 类截屏
    2: 用 ServerSocket 写个服务端,用 Socket 类写个客户端
    3: ServerSocket 把图像字节流发过去
    4: 客户端收到后显示出来就可以了
      

  2.   


    现在我弄到了一张图片可以显示了。。但是我用while循环的时候 第二张图片字节就和第一张的在一起了(图片的大小一直在变大)。。(我是字节传输的)。。
       很乱了。。哎
      

  3.   


    怎么分组啊。。
       大哥我的服务器这端代码是
    import java.awt.Frame;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.Toolkit;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;public class Server extends Frame {
    boolean flag = true;
    File file = null;
    Image image = null;
    Socket socket = null;
    ServerSocket server = null;
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    InputStream is = null;
    static int i = 0;
    public Server() {
    try {
     server = new ServerSocket(6666);
     socket = server.accept();
    } catch (IOException e) {
    e.printStackTrace();
    }
    } public static void main(String[] args) {
    Server server = new Server();
    server.screen();
    server.new MyThread().start();
    } public void paint(Graphics g) {
    g.drawImage(image, 0, 0, this);
    } public void screen() {
    this.setSize(1024, 768);
    this.setLocation(0, 0);
    this.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    System.exit(0);
    }
    });
    this.setVisible(true);
    this.setResizable(true);
    } class MyThread extends Thread { public void run() {
    while (flag) {
    try {
     is = socket.getInputStream();
    File file = new File("e:/test"+i+".jpg");
    FileOutputStream fis = new FileOutputStream(file);
    int j = 0;
    while ((j = is.read()) != -1) {
    fis.write(j);
    }
    fis.flush();
    i++;
    fis.close();
    is.close();
    image = Toolkit.getDefaultToolkit()
    .getImage(file.getPath());
    repaint();
    } catch (IOException e) {
    e.printStackTrace();
    } catch (Exception e) {
    e.printStackTrace();
    flag = false;
    }  }
    }
    }
    }
    怎么改才可以图片更新呢
      

  4.   


    怎么分组啊。。
       大哥我的服务器这端代码是
    import java.awt.Frame;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.Toolkit;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;public class Server extends Frame {
    boolean flag = true;
    File file = null;
    Image image = null;
    Socket socket = null;
    ServerSocket server = null;
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    InputStream is = null;
    static int i = 0;
    public Server() {
    try {
     server = new ServerSocket(6666);
     socket = server.accept();
    } catch (IOException e) {
    e.printStackTrace();
    }
    } public static void main(String[] args) {
    Server server = new Server();
    server.screen();
    server.new MyThread().start();
    } public void paint(Graphics g) {
    g.drawImage(image, 0, 0, this);
    } public void screen() {
    this.setSize(1024, 768);
    this.setLocation(0, 0);
    this.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    System.exit(0);
    }
    });
    this.setVisible(true);
    this.setResizable(true);
    } class MyThread extends Thread { public void run() {
    while (flag) {
    try {
     is = socket.getInputStream();
    File file = new File("e:/test"+i+".jpg");
    FileOutputStream fis = new FileOutputStream(file);
    int j = 0;
    while ((j = is.read()) != -1) {
    fis.write(j);
    }
    fis.flush();
    i++;
    fis.close();
    is.close();
    image = Toolkit.getDefaultToolkit()
    .getImage(file.getPath());
    repaint();
    } catch (IOException e) {
    e.printStackTrace();
    } catch (Exception e) {
    e.printStackTrace();
    flag = false;
    }  }
    }
    }
    }
    怎么改才可以图片更新呢
      

  5.   

    哪个大哥有个完整的截屏还带传输的代码啊。 不要太复杂的,小弟我刚学,我刚学了j2se。不是很懂。所以在练小项目,能给小弟开开眼么
      

  6.   

    唉,失败啊.说好昨天传你的,可是编写时遇到一些问题,毕竟分组有些复杂,而且这是我第二次写分组的程序,嘿嘿.学校断网后才写好.我用两台电脑运行,悲剧啊,一张图片,UDP协议,居然需要10秒钟.实在是个烂程序.不论如何,虽然速度慢,但是没出什么错误.一会儿改进一下,发挥UDP的优势.先把这个破烂程序传上来.
    注意,一共有三个类.其中ByteChange.java,另两个类都要用到的,功能是实现int和byte数组的相互转化.
    另外两个类,一个SendImage.java,用于发送.一个ReceiveImage.java,用于接收并显示.有几点注意的:
    1.SendImage发送时,每发送一个数据包,是要求接收确认包的(这也是传输慢的原因),而且设置了超时时间,如果超时,会输出异常信息,不过程序可以继续执行.所以不要惊讶
    2.ReceiveImage接收时.如果你用的是同一台电脑,显示的时候会发生有趣的反馈现象.嘿嘿,到时候你就知道了.不多说了,下面是程序
      

  7.   

    ByteChange.java/**
     *
     * @author Administrator
     */
    public class ByteChange {
        //将int存入byte数组,使用小端模式
        public static void intToByte(byte b[],int start,int num){
            for(int i=start;i<start+4;i++){
                b[i]=(byte)num;
                num>>>=8;
            }
        }
        //从byte数组中提取int,使用小端模式
        public static int byteToInt(byte b[],int start){
            int num=0;
            for(int i=3+start;i>=start;i--){
                num=num<<8;
                num+=(0xff&(int)b[i]);
            }
            return num;
        }
    }
      

  8.   

    SendImageimport java.awt.image.BufferedImage;
    import java.io.*;
    import java.net.*;
    import java.util.*;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.imageio.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.*;
    public class SendImage {
        //网络参数
        final String addr="192.168.1.4";
        final int myPort=12000;
        final int yourPort=10000;
        //数据包长度,数据长度,标识符长度
        final int bufSize=1024;
        final int dataSize=1000;
        final int identifier=12;
        //用于判断回送包
        final int backNum=10;
        final String backMes="getMessage";
        //
        DatagramPacket packet;
        DatagramSocket socket;
        //数据
        BufferedImage image;
        public SendImage(){
            try{
                socket=new DatagramSocket(myPort);
                socket.setSoTimeout(1000);
                while(true){
                    image = (new Robot()).createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
                    sendImage();
                    try{
                        Thread.sleep(20);
                    }catch(InterruptedException e){
                        
                    }
                }            
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        public void sendImage(){
            try {
                //image = ImageIO.read(new File("Screen.bmp"));
                if(image==null){
                    return;
                }
                int rgbArray[]=new int[image.getWidth()*image.getHeight()];
                image.getRGB(0, 0, image.getWidth(), image.getHeight(), rgbArray, 0, image.getWidth());
                //下面先计算数据大小,分组情况
                //每个数据包的前12个字节为序列号,最后4个字节为结尾标识,所以数据区只有1000个字节
                int size=rgbArray.length*4;
                int number=size/dataSize;
                if(size%dataSize!=0){
                    number++;
                }
                //传送数组组头
                byte b[]=new byte[bufSize];
                fillMessage(0,b);
                //填入number
                ByteChange.intToByte(b, identifier, number);
                //填入总数据大小
                ByteChange.intToByte(b, identifier+4, size);
                //填入image的长度和宽度
                ByteChange.intToByte(b, identifier+8, image.getWidth());
                ByteChange.intToByte(b, identifier+12, image.getHeight());
                packet=new DatagramPacket(b,b.length,InetAddress.getByName(addr),yourPort);
                sendMessage(packet);
                //下面分组发送数据包体
                for(int i=0;i<number;i++){
                    //这里还是用数组b
                    //先清空数组
                    for(int j=0;j<bufSize;j++){
                        b[j]=0;
                    }
                    //填充标识
                    fillMessage(1,b);
                    //填充序列号
                    ByteChange.intToByte(b, identifier, i);
                    //填充数据长度
                    int length=size-dataSize*(i);
                    if(length>dataSize){
                        length=dataSize;
                    }
                    ByteChange.intToByte(b, identifier+4, length);
                    //填充数据  说明一下,length一定是4的倍数
                    int start=dataSize*(i)/4;
                    for(int j=0;j<length;j+=4){
                        ByteChange.intToByte(b, identifier+8+j, rgbArray[start+j/4]);
                    }
                    //发送
                    packet=new DatagramPacket(b,b.length,InetAddress.getByName(addr),yourPort);
                    sendMessage(packet);
                }
            } catch (IOException ex) {
                Logger.getLogger(SendImage.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        public void fillMessage(int category,byte buffer[]){
            if(buffer.length!=bufSize){
                System.out.println("数据包大小错误");
                return;
            }
            switch(category){
                case 0:  //数据头组,包含数据大小,分组多少等信息
                {
                    byte b[]=(new String("[][][][][]01")).getBytes();
                    for(int i=0;i<identifier;i++){
                        buffer[i]=b[i];
                    }
                   break;
                }
                case 1: //数据组体
                {
                    byte b[]=(new String("[][][][][]02")).getBytes();
                    for(int i=0;i<identifier;i++){
                        buffer[i]=b[i];
                    }
                   break;
                }
            }
            byte b[]=(new String("endl")).getBytes();
            for(int i=bufSize-4;i<bufSize;i++){
                buffer[i]=b[i-bufSize+4];
            }
        }
        public void sendMessage(DatagramPacket dp){
            while(true){
                try {
                    socket.send(dp);
                    //发送后要求返回一个标识,否则重发
                    byte b[]=new byte[backNum];
                    DatagramPacket temp=new DatagramPacket(b,b.length);
                    socket.receive(temp);
                    String s=new String(b);
                    if(s.equals(backMes)){
                        //System.out.println("收到回送");
                        break;
                    }
                } catch (IOException ex) {
                    Logger.getLogger(SendImage.class.getName()).log(Level.SEVERE, null, ex);
                }
                
            }
        }
        public static void main(String args[]){
            new SendImage();
        }
    }
      

  9.   

    ReceiveImageimport java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.imageio.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.*;
    import java.io.*;
    import java.net.*;
    import java.util.*;
    public class ReceiveImage {
        //网络参数
        final String addr="localhost";
        final int myPort=10000;
        //final int yourPort=12000;
        //数据包长度,数据长度,标识符长度
        final int bufSize=1024;
        final int dataSize=1000;
        final int identifier=12;
        //用于判断回送包
        final int backNum=10;
        final String backMes="getMessage";
        //
        DatagramPacket packet;
        DatagramSocket socket;
        //数据
        BufferedImage image;
        //显示
        JFrame frame;
        JPanel imagePane;
        JScrollPane contentPane;
        public ReceiveImage(){
            try {
                socket = new DatagramSocket(myPort);
                //socket.setSoTimeout(1000);
                frame=new JFrame();
                imagePane=new JPanel(){
                    public void paint(Graphics g){
                        g.setColor(Color.white);
                        g.fillRect(0, 0, this.WIDTH, this.HEIGHT);
                        if(image!=null){
                            g.drawImage(image, -5, -31, null);
                        }
                    }
                };
                imagePane.setPreferredSize(Toolkit.getDefaultToolkit().getScreenSize());
                contentPane=new JScrollPane(imagePane);
                frame.setContentPane(contentPane);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setBounds(0,0,400,400);
                frame.setVisible(true);
                while(true){
                    getImage();
                    imagePane.repaint();
                }
            } catch (SocketException ex) {
                Logger.getLogger(ReceiveImage.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        public void getImage(){
            byte b[];
            int width,height;
            while(true){
                //先获取数据包头
                b=getMessage();
                //先判断一下数组是不是null
                if(b==null)
                    continue;
                //判断一下,是不是报头
                String head=new String(b,0,identifier);
                if(head.equals("[][][][][]01")){
                    //是报头,跳出循环
                    callBack();
                    break;
                }
            }
            //从报头提取数据包个数信息
            int number=ByteChange.byteToInt(b, identifier);
            int size=ByteChange.byteToInt(b, identifier+4);
            width=ByteChange.byteToInt(b, identifier+8);
            height=ByteChange.byteToInt(b, identifier+12);
            System.out.println("收到数据包头,下面将接收"+number+"个数据包"+",总大小为:"+size+"字节");
            System.out.println("图像长度:"+width+",宽度:"+height);
            //下面分组接收数据
            int rgbArray[]=new int[size/4];
            for(int i=0;i<number;i++){
                //这里还是用数组b
                while(true){
                    b=getMessage();
                    //判断标识
                    String head=new String(b,0,identifier);
                    if(!head.equals("[][][][][]02")){
                        //不是报体,继续循环
                        //不过呢,先判断一下,如果是报头,说明上次的回送不成功,重新回送
                        callBack();
                        continue;
                    }
                    //判断序列号
                    int serial=ByteChange.byteToInt(b, identifier);
                    if(serial==i){
                        //序列号匹配,跳出循环
                        callBack();
                        break;
                    }
                    //如果序列号不匹配,说明以前的回送不成功,重新回送
                    callBack();
                }
                //获取数据长度
                int length=ByteChange.byteToInt(b, identifier+4);
                //攻取数据  说明一下,length一定是4的倍数
                int start=dataSize*(i)/4;
                for(int j=0;j<length;j+=4){
                    //ByteChange.intToByte(b, identifier+8+j, rgbArray[start+j/4]);
                    rgbArray[start+j/4]=ByteChange.byteToInt(b, identifier+8+j);
                }
            }
            image=new BufferedImage(width,height,5);
            image.setRGB(0, 0, width, height, rgbArray, 0, width);
            try {
                ImageIO.write(image, "bmp", new FileOutputStream("1.bmp"));
            } catch (IOException ex) {
                Logger.getLogger(ReceiveImage.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        public byte[] getMessage(){
            try {
                byte[] b = new byte[bufSize];
                packet = new DatagramPacket(b, b.length);
                socket.receive(packet);
                //先判断一下b的最后四个字节是否是文件尾的标志,如果不是,返回null
                String end=new String(b,b.length-4,4);
                if(!end.equals("endl")){
                    return null;
                }            
                return b;
            } catch (IOException ex) {
                Logger.getLogger(ReceiveImage.class.getName()).log(Level.SEVERE, null, ex);
                return null;
            }
        }
        public void callBack(){
            //收到后回送
            byte back[]=(new String("getMessage")).getBytes();
            DatagramPacket dp=new DatagramPacket(back,back.length,packet.getAddress(),packet.getPort());
            try {
                socket.send(dp);
            } catch (IOException ex) {
                Logger.getLogger(ReceiveImage.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        public static void main(String args[]){
            new ReceiveImage();
        }
    }