kostenloser Webspace werbefrei: lima-city


Dateitransfer in Java (TCP) hin und retour

lima-cityForumProgrammiersprachenJava

  1. Autor dieses Themas

    schrotti12

    Moderator Kostenloser Webspace von schrotti12

    schrotti12 hat kostenlosen Webspace.

    Hallo

    Ich will einen ODF-Konvertierungs-Server bauen, welcher mir mit Libreoffice aus Open-Document-Dateien pdfs erstellt. Dieser soll aus Java-Programmen ansprechbar sein.

    Das ganze läuft so ab:

    Client schickt odf-Datei binär an den Server.
    Der Server jagt sie durch die JOD-Bibliothek welche ein horchendes Libreoffice auf dem Server zur Konvertierung verwendet.
    Der Server schickt die pdf-Datei binär an den Client zurück.

    die Verbindung soll über eine TCP-Verbindung laufen.

    Dazu habe ich diesen Server geschrieben, welcher auf Verbindungen wartet und den Transfer sowie die Konvertierung in einem Thread startet:
    package cs.exec;
    
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    import threads.TransporterThread;
    
    public class ConverterServer {
    
    	public static void main(String[] args) {
    		
    		ServerSocket serverSocket = null;
    		int i = 0;
    		
    		try {  
    			serverSocket = new ServerSocket(8101);
    		} catch(IOException e) { 
    			e.printStackTrace();
    		}
    
    		while(i < 10){
    			
    			Socket clientSocket=null;
    			try {
    
    				clientSocket = serverSocket.accept();
    				TransporterThread ct = new TransporterThread(clientSocket);
    				ct.start();
    				
    			} catch(Exception e) {
    				e.printStackTrace();
    			}
    			i++;
    		}
    		
    		try {
    			serverSocket.close();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    }


    Der Thread, welcher die Datei entgegen nimmt, konvertiert und wieder zurück schickt sieht so aus:

    package threads;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    
    import com.artofsolving.jodconverter.DocumentConverter;
    import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
    import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
    import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
    
    public class TransporterThread extends Thread {
    
    	private Socket m_client;
    	private OutputStream m_outputStream;
    	private FileInputStream m_fileInputStream;
    	private InputStream m_socketInputStream;
    	private FileOutputStream m_fileOutputStream;
    	private File m_odt;
    	private File m_pdf;
    
    	public TransporterThread(Socket client) {
    		m_client = client;
    	}
    
    	@Override
    	public void run() {
    		
    		m_odt = new File("document.odt");
    		m_pdf = new File("document.pdf");
    		
    		try {
    			
    			m_socketInputStream = m_client.getInputStream();
    			m_outputStream = m_client.getOutputStream();
    			
    			m_fileOutputStream = new FileOutputStream(m_odt);
    			
    
    			byte[] b1 = new byte[1024];
    			int bytesRead = m_socketInputStream.read(b1);
    
    			while(bytesRead != -1){
    				m_fileOutputStream.write(b1,0,bytesRead);
    				bytesRead = m_socketInputStream.read(b1);
    			}
    			
    			
    			OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
    			connection.connect();
    			DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
    			converter.convert(m_odt, m_pdf);
    			connection.disconnect();
    			
    			m_fileInputStream = new FileInputStream(m_pdf);
    			byte[] b2 = new byte[1024];
    			while(m_fileInputStream.available() > 0){
    				m_outputStream.write(b2, 0, m_fileInputStream.read(b2));
    			}
    			
    			m_fileInputStream.close();
    			m_outputStream.close();
    			
    			m_fileOutputStream.close();
    			m_socketInputStream.close();
    			
    			m_client.close();
    			
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    }


    Der Client ist eine einfache Klasse, welche die Verbindung aufbaut und die odf-Datei schickt.

    package cc.exec;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class Client { 
    
    	public Client(){
    
    	}
    
    	public void convert(String in, String out){
    
    		Socket clientSocket = null;
    		File inFile = new File(in);
    		File outFile = new File(out);
    
    		try { 
    			clientSocket = new Socket("127.0.0.1",13811);
    			
    			OutputStream socketOutputStream = clientSocket.getOutputStream();
    			InputStream socketInputStream = clientSocket.getInputStream();
    			
    			InputStream fileInputStream = new FileInputStream(inFile);
    			FileOutputStream fileOutputStream = new FileOutputStream(outFile);
    			
    			 
    			byte[] buffer = new byte[1024];
    			while (fileInputStream.available() > 0) {
    			    socketOutputStream.write(buffer, 0, fileInputStream.read(buffer));
    			}
    			
    			int bytesRead = socketInputStream.read(buffer);
    			while(bytesRead != -1){
    				fileOutputStream.write(buffer, 0, bytesRead);
    				bytesRead = socketInputStream.read(buffer);
    			}
    			
    			fileOutputStream.close();
    			socketInputStream.close();
    			
    			fileInputStream.close();
    			socketOutputStream.close();
    			
    			clientSocket.close();
    
    		} catch( IOException e) {
    			e.printStackTrace();
    		}
    
    
    		try {
    			clientSocket.close();
    		} catch (IOException e) {
    			
    			e.printStackTrace();
    		}
    
    	}   
    }


    Leider blockieren sich die beiden Seiten. Erst wenn ich den Client terminiere beginnt der Server mit der Konvertierung und kann die Datei dann folglich nicht mehr zurück schicken... Hat vieleicht jemand eine Anleitung, wie ich eine Datei von einem Client zu einem horchenden Server und diese anschließend wieder zurück schicken kann?

    Nicht über die Ports wundern. Läuft über einen TCP-Tunnel...

    Beitrag zuletzt geändert: 6.11.2012 15:20:21 von schrotti12
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Autor dieses Themas

    schrotti12

    Moderator Kostenloser Webspace von schrotti12

    schrotti12 hat kostenlosen Webspace.

    Ich wollte eig. noch folgendes dazu editieren, was das System aber nicht zuließ. Deshalb hier noch eine Erweiterung zum Beitrag:

    Wer das Ding in Eclipse nachbauen will findet die Libraries hier: http://www.artofsolving.com/opensource/jodconverter
    Bzw. ich hab die beiden Projekte in Eclipse hier als Zip-Dateien verpackt: http://tf.schrotti12.eu

    Wie man Libreoffice entsprechend ausführt ist hier nachzulesen: http://www.artofsolving.com/opensource/jodconverter/guide

    Beitrag zuletzt geändert: 6.11.2012 15:21:40 von schrotti12
  4. Du verwendest nicht zufällig eine Hilfs-Mainclasse zum testen die Client und Server zusammen startet? Ich habe die Erfahrung gemacht, dass das unter Umständen (auch bei entkoppelten Threads) Probleme macht.

    Und wo genau bleibt der Server bzw TransporterThread und der Client denn hängen? Die einzigen Methoden die ich im Code sehe die blockieren könnten sind jeweils die .read in Client und TransporterThread bzw die .accept im Server. Alles andere sollte bei einem Fehler eigentlich eine Exception werfen.

    mfg
  5. Autor dieses Themas

    schrotti12

    Moderator Kostenloser Webspace von schrotti12

    schrotti12 hat kostenlosen Webspace.

    Der Server erhält die Datei. Das erkenne ich, wenn ich im Dateisystem nachsehe, dass die Document.odf da ist. Aber die Konvertierung startet nicht mehr. Erst wenn ich den Client stoppe (Strg + C) beginnt der Server die Konvertierung.
    Server und Client laufen auf unterschiedlichen Maschinen...
  6. Wie der Server hängen bleibt habe ich soweit schon verstanden, ich hatte eher auf eine Zeilennummer gehofft.
    Im TransporterThread nehme ich mal an irgendwo zwischen 53 und 57, der Client steht hochstwahrscheinlich in Zeile 39.

    Möglicherweise ist LibreOffice vielleicht doch nicht richtig gestartet und [code=inline]connection.connect();[/code] wartet einfach auf eine Verbindung. Wie genau die Methode funktioniert kann ich dem APIdoc leider nicht entnehmen.
    edit: was für ein Blödsinn, sonst würde es ja nachdem der Client gekillt wird auch nicht gehen -.-

    edit2: Versuch mal den m_fileOutputStream und/oder m_socketInputStream zu schließen, bevor du die Konvertierung startest.

    mfg

    Beitrag zuletzt geändert: 6.11.2012 15:42:47 von syberpsace
  7. Autor dieses Themas

    schrotti12

    Moderator Kostenloser Webspace von schrotti12

    schrotti12 hat kostenlosen Webspace.

    Kanns vieleicht sein, dass ich eine neue Socket-Verbindung aufbauen muss? Ich meine dass ich über eine Verbindung nicht Daten hin und her schicken kann? Wäre ja auch blöd...
    Ich hab auch schon versucht auf Client- und Server-Seite die nicht mehr benötigten Streams zu schließen, aber irgendwie terminiert er dann auch die Socket-Verbindung...
  8. hackyourlife

    Moderator Kostenloser Webspace von hackyourlife

    hackyourlife hat kostenlosen Webspace.

    Das muss doch blockieren, wenn du das so löst ;-)

    Überleg dir mal wie sich diese Zeilen verhalten:
    byte[] b1 = new byte[1024];
    int bytesRead = m_socketInputStream.read(b1);
    
    while(bytesRead != -1){
    	m_fileOutputStream.write(b1,0,bytesRead);
    	bytesRead = m_socketInputStream.read(b1);
    }
    Die Schleife wird so lange laufen wie kein EOF kommt…

    Du hast jetzt 2 Möglichkeiten:
    1) du schickst zuerst die Dateigröße an den Server und liest dann genau so viele Bytes, oder
    2) du machst das so wie bisher, schließt am Client aber nach der Übertragung der ODT-Datei den OutputStream.

    Zu 2)
    Das würde ein EOF beim Lesen verursachen und die Schleife würde abbrechen. Daten kannst du dann trotzdem noch vom Server an den Client schicken.

    Zu 1)
    Bei dieser Methode könnte später noch eine Kommunikation Client → Server stattfinden falls dies benötigt wird, was bei 2) nicht mehr möglich ist.
  9. Autor dieses Themas

    schrotti12

    Moderator Kostenloser Webspace von schrotti12

    schrotti12 hat kostenlosen Webspace.

    Okay, danke! Du hast recht. Er wartet sich wirklch zu Tode. Ich schau mir den Code an und überleg mir, wie ich die Daten übertragen kann. Da komm ich schon noch drauf. Werd das dann nacher veröffentlichen. Ist sicher praktisch, wenn man übers Netzwerk pdfs erstellen kann ohne Libreoffice lokal installieren zu müssen...
  10. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!