Socket Verschiedene Exceptions beim Übertragen von Bildern über Socket

stevey

Aktives Mitglied
Hey Leute,
hab mal wieder ein Problem. Ich versuche zur Zeit in regelmäßigen Abständen(5 sec, später hoffentlich schneller) ein Bild vom Desktop des Clients an den Server zu schicken. Das Bild nehm ich über die Klasse Robot auf und schicke es dann mittels ImageIO.write und einem ObjectOutputStream an den Server. Dieser empfäbgt das Bild und gibt es auf einem Janel aus. Sowohl das Empfangen, als auch das Senden laufen in einem eigenen Thread in einer while(true) Schleife. Hier mal die wichtigsten Codeausschnitte:

Java:
//Client:

oos = new ObjectOutputStream(socket.getOutputStream());

public void run() {
		while(true) {
			try {
				BufferedImage img = r.createScreenCapture(new Rectangle(0,0,1600,900));
				ImageIO.write(img, "png", oos);
				oos.flush();
				oos.reset();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

Java:
//Server:

ois = new ObjectInputStream(cSocket.getInputStream());

public void run() {
		while(true) {
			try {
				BufferedImage img=ImageIO.read(ois);
				if((img) != null){
				     imgPanel.setImg(img);
				     imgPanel.repaint();
				     img = null;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

Dies funktioniert so auch schon oft, aber eben nicht sehr lange, denn es kommen verschiedenste Exceptions beim Empfangen der Bilder. Hier sind mal einige (Zeile 52 in der Fehlermeldung entspricht Zeile 8 im Serverausschnitt):

Java:
java.lang.IllegalArgumentException: Empty region!
	at javax.imageio.ImageReader.computeRegions(Unknown Source)
	at com.sun.imageio.plugins.wbmp.WBMPImageReader.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at server.Server.run(Server.java:52)
(sehr häufig)

javax.imageio.IIOException: Invalid JPEG file structure: two SOI markers
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at server.Server.run(Server.java:52)

java.lang.RuntimeException: New BMP version not implemented yet.
	at com.sun.imageio.plugins.bmp.BMPImageReader.readHeader(Unknown Source)
	at com.sun.imageio.plugins.bmp.BMPImageReader.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at server.Server.run(Server.java:52)

javax.imageio.IIOException: Unsupported JPEG process: SOF type 0xcf
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at server.Server.run(Server.java:52)

javax.imageio.IIOException: Bogus DQT index 15
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at server.Server.run(Server.java:52)

javax.imageio.IIOException: Not a JPEG file: starts with 0xfd 0x6a
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at server.Server.run(Server.java:52)

Ich hoffe das reicht erstmal an Information, damit ihr mir helfen könnt.

Danke, euer stevey 😉
 
Warum schaltest Du dort noch einen [c]ObjectInputStream[/c]/[c]ObjectOutputStream[/c] dazwischen? Nötig sollte es eigentlich nicht sein. Probier es einfach mal direkt mit dem Stream, der vom Socket kommt.
 
also wenn ichs direkt mit den Streams vom Socket versuche, kommt das erste bild problemlos an, aber danach dauert es ewig, bis wieder ein bild übertragen wird, welches nochdazu nur aus schwarz-weiß Rauschen besteht, genauso wie alle nachfolgenden. Auch manche Exceptions von oben treten auf.
 
Hm...also ich stell mal Vermutungen an!
Die Exceptions sehen aus, als ob der ImageIO.read() nicht so richtig weiß, was da genau für ein Bildtyp ankommt (BMP,JPEG...). Heißt die Daten sind irgendwie kaputt gegangen...

Hatte mal ein ähnliches Problem, beim serialisieren von größeren Listen. Damals hab ich zu schnell auf den OutputStream geschrieben und der Empfänger kam nicht mehr mit lesen hinterher.

Ich würde als erstes Versuchen, den sleep() zu erhöhen.
Wenn das keine Besserung bringt, würde ich mir vom Client bestätigen lassen, dass das empfangene Bild ok war. Also ne Art eigenes Protokoll aufsetzen...also nächstes Bild nur senden, wenn der Client das letzte Bild verarbeitet hat und zum erneuten empfangen bereit ist.

Als Quick&Dirty Lösung kannst den Screencapture ja clientseitig auf ein JPanel malen und dieses einfach in den ObjectOutputStream werfen...serverseitig abholen und anstelle deines imgPanel anzeigen.
 
Also der ObjectOutputStream sollte definitiv nicht nötig sein - der ist ja für was ganz anderes da. Wenn es ann beim zweiten Bild "ewig" dauert liegt irgendwas anderes im Argen. Poste ggf. mal welche Exceptions dann kommen, und vielleicht mehr Code...
 
also, wenn ich die Vorschläge von euch beiden umsetze (normale Streams und erst auf anfrage des Servers) funktioniert das ganze schon mal deutlich besser und vor allem länger. Allerdings kommt es hin und wieder doch zu Fehlern. Dazu gehören Exceptions und die Bilder mit schwarz-weiß Rauschen.

Exceptions:
Java:
java.lang.IllegalArgumentException: Empty region!
    at javax.imageio.ImageReader.computeRegions(Unknown Source)
    at com.sun.imageio.plugins.wbmp.WBMPImageReader.read(Unknown Source)
    at javax.imageio.ImageIO.read(Unknown Source)
    at javax.imageio.ImageIO.read(Unknown Source)
    at server.Server.run(Server.java:53)

java.lang.NegativeArraySizeException
	at java.awt.image.DataBufferByte.<init>(Unknown Source)
	at java.awt.image.Raster.createPackedRaster(Unknown Source)
	at java.awt.image.BufferedImage.<init>(Unknown Source)
	at com.sun.imageio.plugins.wbmp.WBMPImageReader.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at server.Server.run(Server.java:53)

Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
	at java.awt.image.DataBufferByte.<init>(Unknown Source)
	at java.awt.image.Raster.createPackedRaster(Unknown Source)
	at java.awt.image.BufferedImage.<init>(Unknown Source)
	at com.sun.imageio.plugins.wbmp.WBMPImageReader.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at javax.imageio.ImageIO.read(Unknown Source)
	at server.Server.run(Server.java:53)
 
Wo und wann diese Exceptions kommen ist nicht ganz klar, aber bei
Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
kann NACHHER "irgendwas" passieren - die JVM ist danach nämlich schon "kaputt".

Speicherst du die Bilder z.B. in einer Liste, die nie wieder geleert wird oder so? Irgendwo müllst du dir offenbar den Speicher voll. Theoretisch kann man mit
java - Xmx1000m DasProgramm
starten, um 1000MB zuzusichern, aber vermutlich tritt der Fehler dann nur später auf - ich kann mir nämlich nicht vorstellen, was dort so viel Speicher brauchen solle, außer einen Memory Leak...
 
nö, in einer Liste speichere ich die nicht ab, aber ich könnte mir vorstellen, dass
Java:
BufferedImage img=ImageIO.read(ois);
manchmal einfach so lange einliest, bis der speicher voll ist, weil der Stream nicht weiß, wann das Bild komplett ist. Und wann eine Exception geworfen wird ist mir bisher auch noch nicht bekannt, es ist meiner Meinung nach nur Zufall...
 
Ist ois immernoch der ObjectInputStream? Eigentlich sollte er schon erkennen, wann ein Bild fertig ist. Am besten wäre Code zum Testen, aber ich vermute, das kann man nicht in wenigen Zeilen zusammenfassen?
 
naja, das geht schon:

Der Server Schaut so aus:
Java:
package server;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.PrintStream;
import java.net.*;

import javax.imageio.ImageIO;
import javax.swing.*;

public class Server extends Thread {
	ServerSocket sSocket;
	Socket cSocket;
	PrintStream out;
	
	JFrame mainFrame;
	JPanel mainPanel;
	ImgPanel imgPanel;
	JTextArea serverConsole;
	
	public Server() throws IOException {
		createGUI();
		sSocket = new ServerSocket(Port);
		writeConsoleMessage("Server started!");
		writeConsoleMessage("waiting for client...");
		cSocket = sSocket.accept();
		writeConsoleMessage("client connected!");
		out = new PrintStream(cSocket.getOutputStream());
		start();
		out.println("ok");
	}
	
	public static void main(String [] args) throws IOException {
		new Server();
	}
	
	public void run() {
		while(true) {
			try {
				BufferedImage img=ImageIO.read(cSocket.getInputStream());
				if((img) != null){
				     imgPanel.setImg(img);
				     imgPanel.repaint();
				     img = null;
				     out.println("ok");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	private void writeConsoleMessage(String msg) {
		serverConsole.append(msg+"\n");
	}
	
	private void createGUI() {
		mainFrame = new JFrame("Fun Programm");
		mainPanel = new JPanel(new BorderLayout());
		
		imgPanel = new ImgPanel(this);
		mainPanel.add(imgPanel, BorderLayout.CENTER);
		
		serverConsole = new JTextArea();
		serverConsole.setEditable(false);
		mainPanel.add(serverConsole, BorderLayout.WEST);
		
		mainFrame.add(mainPanel);
		mainFrame.setPreferredSize(new Dimension(640,420));
		mainFrame.setVisible(true);
		mainFrame.pack();
		
		mainFrame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				try {
					closeConnection();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				System.exit(1);
			}
		});
	}
	
	public void closeConnection() throws IOException{
		if(sSocket != null) {
			sSocket.close();
		}
		if(cSocket != null) {
			cSocket.close();
		}
	}
}
+
Java:
package server;

import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

public class ImgPanel extends JPanel {
	BufferedImage img;
	Server server;
	
	public ImgPanel(Server s) {
		server = s;
	}
	
	public void setImg(BufferedImage img) {
		this.img = img;
	}
	
	public void paintComponent(Graphics g) {
		if(img != null) {
			g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
		}
	}
}

Der Client so:
Java:
package client;

import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class Client extends Thread{
	private Socket socket;
	private BufferedReader in;
	Robot r;
	JFrame frame;
	double screenWidth, screenHeight;
	
	public Client() throws UnknownHostException, IOException {
		frame = new JFrame("Controlled");
		frame.setPreferredSize(new Dimension(200,0));
		frame.setVisible(true);
		frame.pack();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		screenWidth = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
		screenHeight = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
		socket = new Socket("Ip des Routers", Port); //Am besten die öffentliche Ip und nicht die lokale
		in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		try {
			r = new Robot();
		} catch (AWTException e) {
			e.printStackTrace();
		}
		start();
	}
	
	public static void main(String [] args) throws UnknownHostException, IOException {
		new Client();
	}
	
	public void run() {
		while(true) {
			try {
				String msg = in.readLine();
				if(msg.equals("ok")) {
					System.out.println("ok");
					BufferedImage img = r.createScreenCapture(new Rectangle(0,0,(int)screenWidth,(int)screenHeight));
					ImageIO.write(img, "png", socket.getOutputStream());
					socket.getOutputStream().flush();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

ich habs hauptsächlich an meinem eigenen Rechner probiert, also ich war Server und Client gleichzeitig.

gradeben, als ichs nochmal probiert hab, ging es recht lange gut, bis wieder das schwarz-weiß Rauschen kam (siehe Anhang). Das hat sich einmal geändert und dann kam wieder das hier: Thread-0" java.lang.OutOfMemoryError: Java heap space
 
Ja, die Details müßte man sich näher ansehen, aber
socket.getOutputStream()
liefert jedes mal eine neue Instanz einen Streams - dahinter dürfte letztendlich immer dieselbe instanz liegen, aber ... speicher' dir mal am Anfang den OutputStream und verwende dann immer denselben.

Wichtiger: ImageIO verwucht ein Bild zu lesen, aber wie er reagiert (d.h. ob er blockiert oder es ihn raushaut) wenn er nicht sofort ein komplettes Bild lesen kann, müßte man sich näher ansehen. Ein schnelles Suchen in Doku/Code hat dazu nichts ergeben. Aber mach' im Client mal sowas wie
Java:
                InputStream inputStream = cSocket.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(inputStream);
                BufferedImage img=ImageIO.read(bis);
                if((img) != null){
                     System.out.println("read "+img.getWidth()+" "+img.getHeight());
                     imgPanel.setImg(img);
                     imgPanel.repaint();
                     img = null;
                     out.println("ok");
                }
                else
                {
                    System.out.println("READING ERROR");
                }
(Achtung: Dort wird der Stream geschlossen, wenn kein gültiges BufferedImage gelesen werden kann!). Manchmal kann er trotzdem noch kein Bild lesen, aber ... ggf. muss man sich da ein etwas ausgefeilteres Protokoll überlegen.
 
schrittweise vorgehen:
speichere Bilder vom Screenshot als erstes auf der Festplatte, teste sie auf dem Computer, auf dem sie erstellt wurden,
mit externen Bildprogrammen sowie einer Java-GUI (von Festplatte einlesen!)

danach die Datei (von der Festplatte!) an den anderen Socket übertragen, auch dort gleich wieder auf die Festplatte,
mit Bildprogramm testen und dann Java-GUI, was natürlich nicht nur Test sondern ja das letzliche Ziel ist

an welcher Stelle gibt es Fehler?
wenn das Bild beim Client gut (von der Festplatte!) eingelesen werden kann, beim Server aber nicht (von der Festplatte!),
dann untersuche die beiden Dateien, müssen sich ja in irgendeinem byte unterscheiden, prüfe die Übertragung speziell für dieses byte, falls hoffentlich reproduzierbar (nicht mehr mit Screenshot im Client, sondern festen Dummy-Bild, vielleicht auch sehr kleines, testen)

falls alles funktioniert können als nächstes nach und nach Festplatten ausgeklammert werden,
unabhängig voneinander beim Client und/oder beim Server, wann gehts nicht mehr?
auch dann steht im Grunde die byte-Prüfung an..
 
Hmja, ist in diesem Fall vielleicht gar nicht nötig - auf ImageIO kann man sich so gesehen schon verlassen 😉 Die zwei System.out's aus meinem Code hätten schon die wichtigsten Erkenntnisse gebracht: Viele "ERRORS", und dann ein absurd kleines "BufferedImage" - GANZ grob hängt es wohl damit zusammen, dass er das Bild nicht vollständig lesen kann, weil das Netzwerk die Daten nicht schnell genug vollständig liefert.
 
Also ich habs schnell mal ausprobiert und stoße auf die gleichen Probleme.
Nach ein paar Bildern komm nur noch Schrott vom Client.
Zurückverfolgen konnte ich alles bis zum ImageIO...da scheint beim übertragen irgendwas vermurkst zu werden...sieht so aus, als ob deim decodieren irgendwelche ArraySizes total utopische Werte bekommen.

Hab das ganze mal schnell auf ObjectStreams umgeschrieben...die Bilder verpack ich zum Transport in ein ImageIcon. Das ganze braucht sicherlich deutlich mehr Bandbreite und auch mehr CPU, funktioniert aber stabil.

Serverseitig hab ich nach dem Bild empfangen einen Sleep(1000) eingehangen, das hält die CPU-Last unter 5%.

Server:
Java:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

/*
 * Created on 15.02.2012
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */

public class Server extends Thread
{
	ServerSocket sSocket;
	Socket cSocket;
	PrintStream out;

	JFrame mainFrame;
	JPanel mainPanel;
	ImgPanel imgPanel;
	JTextArea serverConsole;

	public Server() throws IOException
	{
		createGUI();
		sSocket = new ServerSocket(62222);
		writeConsoleMessage("Server started!");
		writeConsoleMessage("waiting for client...");
		cSocket = sSocket.accept();
		writeConsoleMessage("client connected!");
		out = new PrintStream(cSocket.getOutputStream());
		start();
		out.println("ok");
	}

	public static void main(String[] args) throws IOException
	{
		new Server();
	}

	public void run()
	{
		try
		{
			int frameCounter = 0;
			ObjectInputStream ois = new ObjectInputStream(cSocket.getInputStream());
			while (true)
			{
				ImageIcon imgIcn = (ImageIcon) ois.readObject();
				if ((imgIcn) != null)
				{
					imgPanel.setImg(imgIcn);
					imgIcn = null;
					frameCounter++;
					System.out.println("Frame#" + frameCounter + " received...");

					//sleep some time
					Thread.sleep(1000);

					out.println("ok");
				}
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
			out.println("ok");
		}
	}

	private void writeConsoleMessage(String msg)
	{
		serverConsole.append(msg + "\n");
	}

	private void createGUI()
	{
		mainFrame = new JFrame("Fun Programm");
		mainPanel = new JPanel(new BorderLayout());

		imgPanel = new ImgPanel(this);
		mainPanel.add(imgPanel, BorderLayout.CENTER);

		serverConsole = new JTextArea();
		serverConsole.setEditable(false);
		mainPanel.add(serverConsole, BorderLayout.WEST);

		mainFrame.add(mainPanel);
		mainFrame.setPreferredSize(new Dimension(640, 420));
		mainFrame.setVisible(true);
		mainFrame.pack();

		mainFrame.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				try
				{
					closeConnection();
				}
				catch (IOException e1)
				{
					e1.printStackTrace();
				}
				System.exit(1);
			}
		});
	}

	public void closeConnection() throws IOException
	{
		if (sSocket != null)
		{
			sSocket.close();
		}
		if (cSocket != null)
		{
			cSocket.close();
		}
	}
}

ImgPanel:
Java:
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

/*
 * Created on 15.02.2012
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */

public class ImgPanel extends JPanel
{
	JLabel picLabel;
	BufferedImage img;
	Server server;

	public ImgPanel(Server s)
	{
		server = s;
		picLabel = new JLabel();
		this.add(picLabel);
	}

	public void setImg(ImageIcon imgIcn)
	{
		//first result from google -> search "resize BufferedImage"
		// Create new (blank) image of required (scaled) size
		BufferedImage scaledImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);

		// Paint scaled version of image to new image
		Graphics2D graphics2D = scaledImage.createGraphics();
		graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		graphics2D.drawImage(imgIcn.getImage(), 0, 0, getWidth(), getHeight(), null);

		// clean up
		graphics2D.dispose();

		picLabel.setIcon(new ImageIcon(scaledImage));
	}
}

Client:
Java:
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.ImageIcon;
import javax.swing.JFrame;

/*
 * Created on 15.02.2012
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */

public class Client extends Thread
{
	private Socket socket;
	private BufferedReader in;
	Robot r;
	JFrame frame;
	double screenWidth, screenHeight;

	public Client() throws UnknownHostException, IOException
	{
		frame = new JFrame("Controlled");
		frame.setPreferredSize(new Dimension(200, 0));
		frame.setVisible(true);
		frame.pack();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		screenWidth = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
		screenHeight = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
		socket = new Socket("localhost", 62222); //Am besten die öffentliche Ip und nicht die lokale
		in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		try
		{
			r = new Robot();
		}
		catch (AWTException e)
		{
			e.printStackTrace();
		}
		start();
	}

	public static void main(String[] args) throws UnknownHostException, IOException
	{
		new Client();
	}

	public void run()
	{
		try
		{
			int frameCounter = 0;
			Rectangle rec = new Rectangle(0, 0, (int) screenWidth, (int) screenHeight);
			ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());

			while (true)
			{
				String msg = in.readLine();
				if (msg.equals("ok"))
				{
					ImageIcon imgIcn = new ImageIcon(r.createScreenCapture(rec));
					oos.writeObject(imgIcn);
					oos.flush();
					oos.reset();
					frameCounter++;
					System.out.println("Frame#" + frameCounter + " done...");
				}
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}

PS: Vergiss nicht IpAdresse und Port wieder anzupassen....
 
dann melde ich mich mal wieder 🙂

@Marco13

ich hab das jetz mal so umgesetzt und die Konsolenausgaben sehen eig. immer so aus:
Java:
//so siehts immer aus, wenns funktioniert
read 1600 900
READING ERROR
READING ERROR
read 1600 900
READING ERROR
READING ERROR
//geht so lange weiter, bis ein Fehler auftritt
Java:
//so sieht ein Fehler aus, bei dem nur noch müll ankommt
read 1600 900
READING ERROR
READING ERROR
READING ERROR
READING ERROR
READING ERROR
read 3 520
READING ERROR
READING ERROR
READING ERROR
READING ERROR
READING ERROR
READING ERROR
//geht unendlich so weiter

@SlaterB

hmm, das alles so zu prüfen wird schweirig, weil ich ja nicht weiß bei welchem Bild der Fehler auftritt. Es werden ja sehr viele verschickt, bevor mal ein fehlerhaftes dabei ist. Es wäre also sehr viel Aufwand auch alle Bilder vor dem Fehler auf deine Punkte hin zu überprüfen.

@daubor

joa, so funktionierts zwar, aber ist dann doch viel zu langsam, Trotzdem danke für deine Mühen

@c_sidi90

wohl falscher Thread, hmm?
 
Ich hatte sowas schonmal (in ausgefeilterer Form) geschrieben, aber dabei eben nicht direkt ImageIO auf den Netzwerkstream angesetzt....
Ein möglicher Versuch:
- Schreib' das Bild zuerst mit ImageIO in einen ByteArrayOutputStream
- Hol' dir davon den byte[] array
- Übertrag' den byte[] array komplett (DEN dann vermutlich am einfachsten mit einem ObjectOutputStream)
- Auf Empfängerseite, aus dem byte[] array einen ByteArrayInputStream bauen
- Lies aus dem ByteArrayInputStream imt ImageIO das Bild.
Nur damit man sicher ist, dass er immer ein komplettes Bild lesen kann, und nicht ImageIO zwischendrin abkackt und 'null' liefert, weil die Netzwerkverbindung nicht mit dem Liefern der Daten hinterherkommt.
 
huch, hab das hier ja total vergessen 😳
wie bekomme ich auf Seiten des Servers denn aus dem ObjectInputStream das byte[] array?
habs jetz mal so gemacht, aber da hängt mein Programm dann einfach...

Java:
ByteArrayOutputStream byteOut = new ByteArrayOutputStream() ;
int i=0 ;
byte[] byteChunk = new byte[4096] ;
while ((i= ois.read(byteChunk))>0) {
	byteOut.write(byteChunk,0,i) ;
}
byte[] b = byteOut.toByteArray() ;
ByteArrayInputStream byteIn = new ByteArrayInputStream(b);
imgPanel.setImg(ImageIO.read(byteIn));
imgPanel.repaint();
 
Die Bedingung müßte >= 0 sein, und bevor man sich den array holt vielleicht noch ein byteOut.flush() / byteOut.close() - ansonsten sollte das nicht ganz falsch sein...
 

Neue Themen


Zurück
Oben