Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 17
  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2012
    Messaggi
    102

    Errore nel trasferimento client server

    Salve! Con l'aiuto di c0der ho risolto in parte il problema di trasferimento! Adesso il tutto non mi da nessun tipo di errori, ma trasferisce un solo screen, e il resto come se non facesse un tubo!

    Sono 4 classi: 2 per il client e 2 per il server, posto il tutto (non sono troppo lunghe)

    Main del client:

    codice:
    import java.awt.*;
    import javax.swing.*;
    import java.net.*;
    
    class Provadef {
    
    	public static void main (String args[]){
    		Socket socket = null;
    		JFrame f = new JFrame ();
    		Robot robot = null;
    		String ip = JOptionPane.showInputDialog("Please enter server IP");
    		String port = JOptionPane.showInputDialog("Please enter server port");
    		int porta = Integer.parseInt(port);
    		f.setLayout(null);
    		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		f.setResizable(true);
    		f.setLocation(0, 0);
    		f.setSize(10, 10);
    		f.setVisible(true);
    		f.setTitle("Terminali video");
    		try {
    			socket = new Socket(ip, porta);
    			(new Transfert(socket)).start();
    		}
    		catch (Exception e){
    			System.out.println("Errore nella creazione del socket");
    		}
    	}
    }
    Transfert del client:

    codice:
    import java.net.*;
    import java.io.*;
    import java.awt.Toolkit;
    import java.awt.Robot;
    import java.awt.Rectangle;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import javax.imageio.*;
    import javax.imageio.stream.*;
    
    class Transfert extends Thread{
    
    	Socket socket;
    	Robot robot;
    	public static int screenWidth = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
        	public static int screenHeight = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
    	
    	public Transfert (Socket socket){
    		this.socket = socket;
    	}
    
    	public void run (){
    		Robot robot = null;
    		ObjectOutputStream out = null;
    		ImageOutputStream iout = null;
    		try {
    			robot = new Robot();
    			out = new ObjectOutputStream(socket.getOutputStream());
    		}
    		catch (Exception e){
    			System.out.println("Impossibile creare lo stream di output");
    		}
    		try {
    			out.writeObject(screenWidth);
    			out.flush();
    			out.writeObject(screenHeight);
    			out.flush();
    			iout = ImageIO.createImageOutputStream(socket.getOutputStream());
    			while (true){
    				BufferedImage image = robot.createScreenCapture(new Rectangle(screenWidth,screenHeight));
    				ImageIO.write(image, "jpg", iout);
    				iout.flush();
    				Thread.sleep(20);
    			}
    		}
    		catch (IOException ex){
    			System.out.println("Impossibile trasferire dati sull'output");
    		}
    		catch (InterruptedException ex){
    			System.out.println("...");
    		}
    	}
    }
    Main Sever:
    codice:
    import java.awt.*;
    import javax.swing.*;
    import java.net.*;
    import java.io.*;
    
    class Server {
    
    	public static void main (String args[]){
    		ServerSocket sSocket = null;
    		Socket socket;
    		JFrame f = new JFrame ();
    		JPanel p = new JPanel ();
    		f.setLayout(null);
    		String port = JOptionPane.showInputDialog("Please enter server port");
    		int porta = Integer.parseInt(port);
    		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		f.setResizable(true);
    		f.setSize(500, 500);
    		try {
    			sSocket = new ServerSocket (porta);
    			while (true){
    				System.out.println("Attesa connessione...");
    				socket = sSocket.accept();
    				System.out.println("Connessione stabilita!");
    				f.setVisible(true);
    				(new Recieve(f, p, socket)).start();
    			}
    		}
    		catch (Exception e){
    			System.out.println("Impossibile creare socket del server");
    		}
    	}
    }
    Recieve Server:
    codice:
    import java.awt.*;
    import javax.swing.*;
    import java.net.*;
    import java.io.*;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import javax.imageio.*;
    import javax.imageio.stream.*;
    
    class Recieve extends Thread{
    	
    	JFrame f;
    	JPanel p;
    	Socket socket;
    	
    	public Recieve (JFrame f, JPanel p, Socket socket){
    		this.f = f;
    		this.p = p;
    		this.socket = socket;
    	}
    	
    	public void run (){
    		ObjectInputStream in = null;
    		ImageInputStream iin = null;
    		BufferedImage image = null;
    		int screenWidth = 800;
    		int screenHeight = 600;
    		try {
    			in = new ObjectInputStream(socket.getInputStream());
    			screenWidth = (int) in.readObject();
    			screenHeight = (int) in.readObject();
    			System.out.println("Valore x: " + screenWidth);
    			System.out.println("Valore y: " + screenHeight);
    		}
    		catch (Exception e){
    			System.out.println("Impossibile aprire flusso di input");
    		}
    		f.getContentPane().add(p);
    		p.setBounds(0, 0, screenWidth, screenHeight);
    		try {
    			iin = ImageIO.createImageInputStream(socket.getInputStream());
    			while (true){
    				image = ImageIO.read(iin);
    				Graphics g = p.getGraphics();
    				g.drawImage(image, 0, 0, null);
    				Thread.sleep(20);
    			}
    		}
    		catch (IOException e){
    			System.out.println("Impossibile ricevere segnale video");
    		}
    		catch (InterruptedException e){
    			System.out.println("...");
    		}
    		try {
    			socket.close();
    		}
    		catch (Exception ex) {}
    	}
    }

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Non ho modo di effettuare un test sul tuo codice, ma a vederlo direi che non stai separando correttamente i thread dai componenti grafici (la tua finestra viene creata all'interno dello stesso thread che si occupa di effettuare le operazioni di I/O) e l'EDT ne viene influenzato.

    Dovresti spostare la finestra in una classe a parte, in modo da avere la gestione del I/O in un thread separato che, al momento opportuno, andrà a informarla della nuova immagine.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2012
    Messaggi
    102
    Originariamente inviato da LeleFT
    Non ho modo di effettuare un test sul tuo codice, ma a vederlo direi che non stai separando correttamente i thread dai componenti grafici (la tua finestra viene creata all'interno dello stesso thread che si occupa di effettuare le operazioni di I/O) e l'EDT ne viene influenzato.

    Dovresti spostare la finestra in una classe a parte, in modo da avere la gestione del I/O in un thread separato che, al momento opportuno, andrà a informarla della nuova immagine.


    Ciao.
    Ok, allora apporto qualche modifica e ti faccio sapere!!

  4. #4
    Utente di HTML.it
    Registrato dal
    Feb 2012
    Messaggi
    102
    LeleFT, niente da fare! Ho apportato le modifiche, e non era l'EDT il problema, è sul CLIENT!

    codice:
    import java.awt.Robot;
    import java.awt.Rectangle;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import javax.imageio.*;
    import javax.imageio.stream.*;
    
    class Transfert extends Thread{
    
    	Socket socket;
    	public static int screenWidth = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
        	public static int screenHeight = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
    	
    	public Transfert (Socket socket){
    		this.socket = socket;
    	}
    
    	public void run (){
    		Robot robot = null;
    		ObjectOutputStream out = null;
    		ImageOutputStream iout = null;
    		GraphicsEnvironment gEnv=GraphicsEnvironment.getLocalGraphicsEnvironment();
      		GraphicsDevice gDev=gEnv.getDefaultScreenDevice();
    		try {
    			robot = new Robot(gDev);
    			//out = new ObjectOutputStream(socket.getOutputStream());
    		}
    		catch (Exception e){
    			System.out.println("Impossibile creare lo stream di output");
    		}
    		try {
    			/*out.writeObject(screenWidth);
    			out.flush();
    			out.writeObject(screenHeight);
    			out.flush();
    			out.reset();
    			iout = ImageIO.createImageOutputStream(socket.getOutputStream());*/
    			while (true){
    				iout = ImageIO.createImageOutputStream(socket.getOutputStream());
    				System.out.println("Sono dentro while");
    				BufferedImage image = robot.createScreenCapture(new Rectangle(screenWidth,screenHeight));
    				ImageIO.write(image, "jpg", iout);
    				System.out.println("Sono dopo imageio.write");
    				Thread.sleep(20);
    			}
    		}
    		catch (IOException ex){
    			System.out.println("Impossibile trasferire dati sull'output");
    		}
    		catch (InterruptedException ex){
    			System.out.println("...");
    		}
    	}
    }
    Esattamente nella riga di *ImageIO.write(image, "jpg", iout);*
    Mi trasferisce solo la prima volta, dalla seconda si blocca sull'istruzione e non fa andare avanti il loop del while! Lo sono riuscito a capire dalle println() prima e dopo di write(). E' strano, ho provato tutti i metodi per aggiornare lo stream ( reset(), flush(), mark() ) ma niente, niente di niente! Secondo me utilizzo male questo speciale flusso per le BufferedImage...
    Io tornerei ad usare un normale ObjectOutputStream con una ImageIcon, ma il maledetto compilatore mi da perennemente questo problema:


    codice:
    Exception in thread "main" java.lang.SecurityException: SHA MessageDigest not available
    e online non si trova praticamente nulla al riguardo! Vi prego sono bloccato in sto trasferimento e non posso andare avanti col mio progetto, se mi date una mano ve ne sono veramente grato!

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Io spezzo ancora una lancia a favore di un semplice trasferimento binario
    Se qualcuno te lo risolve con la serializzazione ben venga,

    ma vorrei aggiungere che la serializzazione è particolarmente comoda quando hai
    10 tipi di pacchetti, e non vuoi metterti a fare marshalling/unmarshalling a mano.
    Ma qui hai (almeno per ora) 1 solo tipo di pacchetto, che in più ti sta dando problemi.
    Inoltre avresti la compatibilità verso altri client o server scritti in altri linguaggi.
    Se avanzo un momento scrivo una mini-demo che il programmino mi interessa cmq.

  6. #6
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Ciao ti allego la mia implementazione senza serializzazione.
    È volutamente ridotta all'osso, solo per vedere che funzioni.
    Ciao.

    codice:
    // client
    import java.net.*;
    import java.io.*;
    import java.awt.Robot;
    import java.awt.Rectangle;
    import java.awt.image.BufferedImage;
    import javax.imageio.*;
    import javax.swing.JOptionPane;
    
    class Provone {
        public static void main (String args[]){
            ByteArrayOutputStream baos;
            DataOutputStream dos;
            BufferedImage image;
            Socket socket;        
            Robot robot;
            byte buf[];  
            String ip = JOptionPane.showInputDialog("Please enter server IP");
            String port = JOptionPane.showInputDialog("Please enter server port");
    
            try {
                robot = new Robot();
                socket = new Socket(ip, Integer.parseInt(port));
                while (true) {
                    // capture
                    image = robot.createScreenCapture(new Rectangle(1024, 768));
                    // dump
                    baos = new ByteArrayOutputStream();
                    ImageIO.write(image, "jpeg", baos);
                    baos.flush();
                    buf = baos.toByteArray();
                    baos.close();
                    // send
                    dos = new DataOutputStream(socket.getOutputStream());
                    dos.writeInt(buf.length);
                    dos.write(buf);
                }
            } catch (Exception e){
                e.printStackTrace();
            }			
        }
    }
    codice:
    // server
    import java.net.*;
    import java.io.*;
    import java.awt.FlowLayout;
    import javax.swing.*;
    import java.awt.image.BufferedImage;
    import javax.imageio.*;
    
    class Provone2 extends JFrame implements Runnable {
        private ServerSocket serverSocket;
        private JLabel label;
    
        public Provone2() {
            String port;
    
            // UI
            getContentPane().setLayout(new FlowLayout());
            label = new JLabel();
            add(label);		
            setSize(1024, 768);
            // socket
            port = JOptionPane.showInputDialog("Please enter server port");
            try {
                serverSocket = new ServerSocket(Integer.parseInt(port));
            } catch (IOException e) {
                e.printStackTrace();
            }
            new Thread(this).start();        
        }
    
        public void run() {
            BufferedImage image;
            DataInputStream dis;
            Socket socket;        
            byte buf[];
            int len;
        
            try {
                socket = serverSocket.accept();
                System.out.println("client accettato");
                while (true) {
                    // receive
                    dis = new DataInputStream(socket.getInputStream());
                    len = dis.readInt();
                    buf = new byte[len];
                    dis.readFully(buf);
                    // parse
                    image = ImageIO.read(new ByteArrayInputStream(buf));
                    // draw
                    label.setIcon(new ImageIcon(image));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }	    
        }
    
        public static void main (String args[]){
            new Provone2().setVisible(true); 
        }
    }

  7. #7
    Utente di HTML.it
    Registrato dal
    Feb 2012
    Messaggi
    102
    Grazie c0der, più tardi provo!

    Intanto ti avviso che ho riscontrato varie problematiche:

    - dal mio pc (agendo col socket in localhost) parte tutto, anche la fatidica ImageIcon che dava lo SHA Exception
    - dal pc in salone (agendo col socket con ip locale) mi da SHA Exception (non ho provato la scomposizione in byte)
    - dal pc di un mio amico (agendo col socket in ip pubblico) non vuole saperne completamente niente... mi da errore sulla creazione del socket di tipo IOException!

    Della seconda soluzione mi interessa poco, ma della terza sai dirmi nulla??

    PS la terza soluzione anche facendolo dal mio stesso pc, ma digitando l'ip pubblico, non vuole saperne il socket di trasferire i dati...

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Non so se ho capito bene: ti fallisce sul client la connessione al server, ossia questa riga?
    socket = new Socket("IP PUBBLICO SERVER", PORTA);

    Qui non solo viene creato il socket, ma viene fatta la connessione al server.
    Non è che quel server sta dietro un router/firewall e quindi devi aprire la porta sul firewall e fare il port forwarding?

  9. #9
    Utente di HTML.it
    Registrato dal
    Feb 2012
    Messaggi
    102
    Originariamente inviato da c0der
    Non so se ho capito bene: ti fallisce sul client la connessione al server, ossia questa riga?
    socket = new Socket("IP PUBBLICO SERVER", PORTA);

    Qui non solo viene creato il socket, ma viene fatta la connessione al server.
    Non è che quel server sta dietro un router/firewall e quindi devi aprire la porta sul firewall e fare il port forwarding?
    Ehmmm, certo che è in un router, è il mio pc desktop usuale! E per il port forwarding come devo procedere? Non so come procedere per java... ho un alice gate plus 2 wi-fi!

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Se mi confermi che la situazione è
    pc1(Provone) ---- router1 ======= (internet) ======= router2 ---- pc2(Provone2 in ascolto su 1234)

    allora sul router2 devi andare nella pagina di configurazione:
    1) nella parte "firewall" WAN=>LAN mettere un "allow" per la porta 1234 (e per sicurezza potresti mettere come "source ip" non "All" ma l'ip pubblico di router1)
    2) nella parte "nat/port forwarding" aggiungere una regola che le richieste alla porta 1234
    vengano forwardate all'indirizzo ip "interno" di pc2 (esempio 192.168.1.10)

    Tutto ciò sul alice gate plus 2 mi pare di capire che si chiami Port Mapping/Virtual Server,
    i concetti sono gli stessi, con le istruzioni di sopra dovresti ritrovarti.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.