Wie spreche ich einen Thread an?

Paul279

Aktives Mitglied
Hallo liebe Community,

jetzt steh ich vor einem Problem, dass ich ohne euch nicht lösen kann.

Ich habe ein Programm geschrieben, das Auswertungen durchführt.
Funktioniert tadellos.

Habe eine Klasse erzeugt(serverThread), die nur auf Anfragen von Clients reagiert. Wenn ein Client sich auf einen Socket verbindet, wird die Klasse serverThread2 gestartet. Somit habe ich für jeden Client einen eigenen serverThread2.

serverThread:
Java:
package myserver;

import java.io.IOException;
import java.net.ServerSocket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Asus Schlappi
 */
public class serverThread extends Thread{
     
     private ServerSocket serverSocket = null;

    public serverThread(ServerSocket serverSocket) {
    this.serverSocket = serverSocket;
    }
    

    public void run() {
            
        boolean listening = true;
        try {
            while (listening)     
            new serverThread2(serverSocket.accept()).start();
        
            serverSocket.close();
        } catch (IOException ex) {
            Logger.getLogger(serverThread.class.getName()).log(Level.SEVERE, null, ex);
        }                        
    }    
}

ServerThread2:
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package myserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Paul
 */
public class serverThread2 extends Thread{

    private Socket socket = null;
    String vomClient;
    String zumClient; 
    PrintWriter out;
    BufferedReader in;
    
    serverThread2(Socket accept) {
        super("serverThread");
	this.socket = socket;
        System.out.println("Vor beim Server");
    }
 
    public void run() {
    	try {
	    out = new PrintWriter(socket.getOutputStream(), true);
	    in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            zumClient = "START";
            out.println(zumClient);
	    while ((vomClient = in.readLine()) != null) {
		
                //out == damit wird alles zum Client geschickt
                out.println(zumClient);
                
		
                
                //Clientverbindung schließen
                if (zumClient.equals("Bye"))
		    break;
	    }
	    out.close();
	    in.close();
	    socket.close();

	} catch (IOException e) {
	} 
    }
    
}

Gut, die Verbindung steht, man könnte kommunizieren.

Das Problem:
Im serverThread steht:
Java:
new serverThread2(serverSocket.accept()).start();

somit kann ich den Thread nicht wie ein normales Objekt ansprechen. Also logisch für mich hätte es so funktionieren müssen:
serverThread2 meinServerThread2 = new serverThread2(serverSocket.accept()).start();

Leider funktioniert das nicht so.
Ich möchte aber gerne den Thread irgendwie ansprechen können, denn wenn in meinem Auswertungssystem ein Button "Senden" gedrückt wird, soll auch eine Message an einen speziellen Client (serverThread2) gelangen.

Also kurz gesagt:
Wie spreche ich meinen Thread an, übergebe ihm Werte und bekomme auch Rückmeldungen?

Ich hoffe, dass alles verständlich ist.
Mfg
Paul
 

parabool

Bekanntes Mitglied
Java:
serverThread2 meinServerThread2 = new serverThread2(serverSocket.accept());
meinServerThread2.start();
 

Paul279

Aktives Mitglied
danke sehr, aber es hilft mir nicht ganz weiter

Hier mein Code:
Java:
public class serverThread extends Thread{
     
    private ServerSocket serverSocket = null;

    serverThread2[] meineServerThreads;
    int i = 0;
    
    public serverThread(ServerSocket serverSocket) {
    
        this.serverSocket = serverSocket;
        this.meineServerThreads = new serverThread2[25];
    }
    

    public void run() {
            
        boolean listening = true;
        try {
            while (listening)     
            i++;
            //new serverThread2(serverSocket.accept()).start();
            meineServerThreads[i] = new serverThread2(serverSocket.accept());
            meineServerThreads[i].start();
            
            serverSocket.close();
        } catch (IOException ex) {
            Logger.getLogger(serverThread.class.getName()).log(Level.SEVERE, null, ex);
        }                        
    }    
}

Warum geht er nicht in meinServerThreads[1].start ?
er geht in "meineServerThreads[1] = new serverThread2(serverSocket.accept());" hinein, aber macht dann nicht weiter ???
 
Zuletzt bearbeitet:

Paul279

Aktives Mitglied
Ahhh so ein dummer Fehler von mir.

Danke sehr, scheint zu funktionieren :)

Gibt es noch eine Möglichkeit, die "meineServerThreads" dynamisch zu machen.
Also dass ich diese nicht auf 25 beispielsweise begrenze.
Jetzt habe ich ja begrenzt:

this.meineServerThreads = new serverThread2[25];

Einfach 100 reinschreiben möchte ich nicht, da es sehr hässlich ist und auch nicht performant.

Danke sehr
 

Michael...

Top Contributor
Jetzt habe ich ja begrenzt:

this.meineServerThreads = new serverThread2[25];

Einfach 100 reinschreiben möchte ich nicht, da es sehr hässlich ist und auch nicht performant.
Es gibt auch Lists z.B. ArrayList. Die sind dynamisch erweiterbar. Allerdings macht es wenig Sinn Referenzen auf einen Thread zu halten. Zur Kommunikation musst Du Referenzen auf die In- und OutputStreams der Clients halten und nur den InputStream in einem separaten Thread auslesen.
 

Paul279

Aktives Mitglied
uh danke sehr. Klingt alles schon ziemlich "hoch".
Aber ich glaube, dass ich weiß was du meinst.

Werde ich ausprobieren.
Danke sehr
 

jamesv

Bekanntes Mitglied
Michael, könntest du das eventuell etwas erläutern? HAst du einen Link dazu, dass interessiert mich jetzt aber, wie man so etwas realisiert. Habe noch nie etwas mit Netzwerk/Threads gemacht xD

Thx.
--
Edit:

Bzw. warum man die In/Output streams referenzieren muss.
 

Paul279

Aktives Mitglied
Entschuldige ich brauche wieder Hilfe bei diesem Thema.

Ich schaffe es, Dateien hin und her zu senden, aber immer nur Strings.

Wie kann ich ein ganzes Object oder ArrayList senden aber auch empfangen?

Danke sehr
 
S

Spacerat

Gast
Hoch veehrter Herr Thread
Ich, als Ihr Schöpfer fände es angenehm, wenn Sie auch mal andere Dinge im Netz hin und her bewegen würden, als immer nur Strings.
:lol:

@TO: Kennst du den Serializable-Mechanismus? In diesem Fall, eignet er sich zur Abwechslung auch mal. Die meisten User wollen damit aber immer blos Dateien laden und speichern und dann rät man davon ab. Für deinen Fall aber ist er hervorragend geeignet.
 

Paul279

Aktives Mitglied
So es ist 2 Uhr früh und ich muss ins Bett, morgen wird wieder ein schei* Tag in der Arbeit :-(

@Spacerat: Nein sagt mir leider gar nichts, aber ich hoffe es geht irgendwie so, wie ich es jetzt gemacht habe.

Nun habe ich alles neu gemacht:
Mein Server:
Java:
package myserver;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;

/**
 *
 * @author Asus Schlappi
 */
public class serverThread extends Thread{
    
    ArrayList<ObjectOutputStream> clientstreams = new ArrayList<>();    
    private ServerSocket mySocket;

 
    public serverThread(ServerSocket serverSocket) {
        this.mySocket = serverSocket;
    }
    
    public void run() {
        while(true){
            try {
                System.out.println("Ready to receive");
                Socket client = mySocket.accept();
                clientstreams.add(new ObjectOutputStream(client.getOutputStream()));
                System.out.println(client.getInetAddress().getHostAddress()+" connected to the Server");
                Thread t = new Thread(new ClientHandler(client));
                t.start();
            } catch (IOException e) {
                // TODO Auto-generated catch block
            }
        }
    }
    
    public void shareToAll(Object objectToSchare){
        for(ObjectOutputStream stream:clientstreams){
            try {
                stream.writeObject(objectToSchare);
                stream.flush();
            } catch (IOException e) {
                // TOD  O Auto-generated catch block
            }
        }
    } 
        
    
    private class ClientHandler implements Runnable{
        Socket clientSocket;

        public ClientHandler(Socket clientSocket){
            this.clientSocket = clientSocket;
        }
        
        @Override
        public void run() {
            try {
                ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
                while(true){
                    try {
                        ois.readObject();

                    } catch (ClassNotFoundException | IOException e) {
                        // TODO Auto-generated catch block
                    }
                }
            }catch(SocketException e){
                System.out.println(clientSocket.getInetAddress().getHostAddress()+" disconnected from the Server");
                clientstreams.remove(clientSocket);
            }catch (IOException e) {
                // TODO Auto-generated catch block
            }
        }
    }   
 
}

MeinClient:
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package client;

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 *
 * @author Paul
 */
public class clientThread {
 
    ObjectOutputStream  out;
    ObjectInputStream  in;

    public clientThread(String ip, int port) throws UnknownHostException, IOException {
        connect(ip, port);
    }
    
    public void connect(String ip, int port) throws UnknownHostException, IOException {
        Socket socket = new Socket(ip, port);
        out = new ObjectOutputStream(socket.getOutputStream());
        in = new ObjectInputStream(socket.getInputStream());
    } 
    
    public void send(Object message) throws IOException {
        if(out == null) throw new IOException();
        out.writeObject(message);
        out.flush();
    }
 
    public Object receive() throws IOException{
        try {
            return in.readObject();
        } catch (ClassNotFoundException e) {
            throw new IOException();
        }
    }
    
}

Dieser Nachbau ist von diesem gefundenen Forumsbeitrag (Klick mich. Habe gemeint, dass ich es verstehe, aber leider schaltet mein Kopf bei
Java:
 ois.readObject();
komplett ab.

Also was funktioniert/wo ist der Fehler:
Server startet. Der Client verbindet sich zum Server.

Ich rufe die Methode "shareToAll" beim Server auf und sende einfach "Hallelulja" zum Beispiel.

Beim Client tut sich rein gar nichts.
Der Server geht in die Klasse ClientHandler hinein und geht bei "ois.readObject();" nicht weiter.

Was muss ich tun? Muss der Client das irgendwie "abholen" oder was passiert beim ois.readObject(); ?

Hoffe dass mir ein Java Guru weiterhelfen kann. Geh jetzt etwas verzweifelt ins Bett :bahnhof:
Wünsche eine gute Nacht
 
S

Spacerat

Gast
So einfach geht's natürlich nicht. Ein ObjectStream muss zwischenzeitlich auch mal geschlossen werden, weil sonst laufen die HandleTables über und vieles mehr. Will man also, dass die Socket-Streams geöffnet bleiben, so muss man die Objekte z.B. in ein ByteArrayStream kapseln und dessen ByteArray senden. Andernfalls steht da in deinem Link auch etwas davon, dass man die ObjectOutputStreams gleich nach ihrer Initialisierung flushen sollte, damit er einen initialen Header sendet und die Empfänger nicht ewig auf ein Objekt warten, was niemals kommt.
 

Paul279

Aktives Mitglied
Könntest du mir bitte zeigen wie ich so etwas realisiere, mit dem flushen, dass er nur einen initialen Header sendet und ich das dann Empfangen kann.

Steh dermaßen auf der Leitung
 
S

Spacerat

Gast
Also bisher schreibst du:
Java:
clientstreams.add(new ObjectOutputStream(...))
daraus machst du:
Java:
ObjectOutputStream oos = new ObjectOutputStream(...);
clientstreams.add(oos);
oos.flush();
Wenn ich das richtig gelesen hab'.
 
S

Spacerat

Gast
ois.readObject() wartet auf ein Object.
Flushen nützt da wenig.
Gut erkannt, dass ist genau der Punkt. Damit es das nicht tut, muss der OutputStream geflushed werden, bevor der InputStream geöffnet wird.
the ObjectInputStream constructor reads data from the given InputStream. in order for this to work, you must flush the ObjectOutputStream immediately after constuction (to write the initial header) before you attempt to open the ObjectInputStream. also, if you want to send more than one object per connection, you must open the ObjectOutputStream once and use it for the lifetime of the socket (e.g. your shareToAll method).
 

Paul279

Aktives Mitglied
Okay, auch wenn es nicht geflusht werden muss.
Habe es mal umgeschrieben auf das:
Java:
ObjectOutputStream oos = new ObjectOutputStream(...);
clientstreams.add(oos);
oos.flush();

Und wie kann der Client jetzt etwas empfangen? Client reagiert überhaupt nicht ?
 
S

Spacerat

Gast
Na sowas. Was muss man dann machen, damit readObject() nicht bis zum Ende aller Tage auf Objekte wartet, die auf der anderen Seite bereits durch den Aufruf von shareToAll() geschrieben wurden?
[EDIT]:oops: Überschneidung. Wenn's jetzt tatsächlich nicht am flush() liegt, gebe ich mal vertrauensvoll an kaetzacoatl ab.[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:

kaetzacoatl

Bekanntes Mitglied
this.socket = socket;

Daran liegts!
Der client hat keine Verbindung
zum server!

Tipp: benutz eine IDE!
dann hättest du
Fehler sofort
gefunden.
 

Paul279

Aktives Mitglied
So liebe Leute
gestern habe ich mal schlafen müssen, war fertig von der Woche und der Nacht davor :rtfm:

Nein es liegt nicht am socket = socket, da ich ja oben geschrieben habe, dass ich alles neu gecodet habe.J etzt habe ich, bevor ich alles erkläre, einfach mein Programm (server + client) gepackt und zum Download bereitgestellt. Zum Download

PS: Das Programm bleibt jetzt bei ois.readObject() stehen und macht keine Endlosschleife. :)

Fragt mich aber nicht was es genau war, habe eigentlich nur gelöscht. Aber seht mal selbst

Das Thema endet hier leider nicht.
Diese Sockets machen mich fertig.

Problem:
Ich habe keine Ahnung, wie ich nun das Object beim Client speichern kann.
Es gibt zwar eine Funktion beim Client:
Java:
    public Object receive() throws IOException{
        try {
            return in.readObject();
        } catch (ClassNotFoundException e) {
            throw new IOException();
        }
    }

Aber woher soll man jetzt beim Client wissen, dass er was bekommen hat?
In meinem Kopf ist das so:
Server sendet, client müsste in einer while sein und sobald er was empfängt macht er was.

Jetzt steht nur "return in.readObject();" ja wohin returnt er das?

Tut mir leid, wenns jetzt schon sehr viel ist, aber leider verstehe ich das nicht (Mein Kopf ???:L )

PS: Das Projekt ist in Netbeans programmiert. Beim Server kann man die Klasse serverThread2 einfach lassen, die ist für nichts gut. Da hab ich nur probiert. Eigentlich braucht man die Datenbank nicht für mein Programm, müsste aber trotzdem gehn, da die Datenbank mit im Paket dabei ist.
(Server/DatenbankFiles)
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
F http Post auf einen Grafana Server Netzwerkprogrammierung 3
izoards Mehrere TCP Verbindungen auf einen Server [alles Local] Netzwerkprogrammierung 2
S Java: Anbindung an einen realen Server? (+ Portfreigabe) Netzwerkprogrammierung 8
X Kann ich einen Client/Server verbindung hinkriegen die mir alle paar Sekunden die aktuellen Daten per Realtime zuschickt ? Netzwerkprogrammierung 9
E Kurze Textnachrichten über einen Server von meinem Handy auf den Computer laden. Netzwerkprogrammierung 9
D Socket Message an einen Server senden? Netzwerkprogrammierung 8
C Inhalt einer .JPG Datei in einen OutputStream schreiben? Netzwerkprogrammierung 10
M jsf-seite beim hinzufügen einer csv-datei in einen ordner aktualiseren Netzwerkprogrammierung 0
C Client connection per Portforwarding auf einen lokalen Serverport Netzwerkprogrammierung 3
P Was brauche ich alles / wo sollte ich einen Blick drauf werfen? Netzwerkprogrammierung 17
E Wie kann man einen einfachen E-Mail Server schreiben Netzwerkprogrammierung 2
T HTTP Einen HTTP Server erstellen Netzwerkprogrammierung 20
Z Socket [Chatprogramm] Mehrere Clients an einen Server Netzwerkprogrammierung 10
N Einen Server als ausführbare Datei exportieren Netzwerkprogrammierung 15
C Socket Probleme beim Lesen und Schreiben aus/in einen Socket Netzwerkprogrammierung 2
M Socket JavaProg über einen Clienten steuern Netzwerkprogrammierung 5
I HTTP Grundlagen um einen Webserver zu erstellen Netzwerkprogrammierung 17
C An WebDAV einen "MKCOL" Befehl versenden Netzwerkprogrammierung 4
D Schreiben auf einen TCP/IP Socket Netzwerkprogrammierung 2
K HTTP-Anfrage an einen Server wird nicht beantwortet Netzwerkprogrammierung 3
H String Array durch einen Stream schicken. Netzwerkprogrammierung 4
L Mit Java auf Forum einloggen und dann einen Threat erstellen Netzwerkprogrammierung 4
R Mehrere Dateien über einen Socket senden Netzwerkprogrammierung 2
L mehrere Streams über einen Socket? Netzwerkprogrammierung 8
A Wichtig für einen Chat? Netzwerkprogrammierung 4
V Mehrere Streams durch einen Stream senden Netzwerkprogrammierung 14
V PC der an einen Router angeschlossen ist aus dem... Netzwerkprogrammierung 13
V Einen Eintrag aus einer Zip Datei von einem Server laden Netzwerkprogrammierung 2
M Wie programmiere ich einen FTP - Server Netzwerkprogrammierung 2
André B. In einen InputStream schreiben? Netzwerkprogrammierung 6
T Html-Source über URL in einen String speichern? Netzwerkprogrammierung 16
P Verschiedene Daten über einen Stream Netzwerkprogrammierung 4
U Einen HandlerThread, der mehrere Verbindungen verwaltet? Netzwerkprogrammierung 2
T Mit FTP verbinden, einen Ordner erstellen und Datei löschen Netzwerkprogrammierung 3
M Socket Verbindungen für einen Chat Netzwerkprogrammierung 10
T file auf einen server laden Netzwerkprogrammierung 4
A Zugriff auf einen fremden Monitor im lan Netzwerkprogrammierung 3
OnDemand Thread und Ratelimiter Netzwerkprogrammierung 4
F Thread "extern" beenden Netzwerkprogrammierung 3
OnDemand Linux RAM per Thread Netzwerkprogrammierung 3
V Socket Audio Clip loopen ohne neuen Thread Netzwerkprogrammierung 2
C Thread Netzwerkprogrammierung 9
platofan23 Socket Hilfe mit Socket Thread und ArrayList Netzwerkprogrammierung 6
A RMI RMI - Thread Objekte übertragen und auf anderer Machine weiterlaufen lassen Netzwerkprogrammierung 0
S Socket ThreadPool oder Thread pro Client? Netzwerkprogrammierung 11
T Socket Server starten Thread Problem Netzwerkprogrammierung 12
M Thread Scheduler Java 5.0? Netzwerkprogrammierung 2
7 Mehrere Verbindungen gleichzeitig in einem Thread mit ApacheHTTP Netzwerkprogrammierung 7
D Socket Dynamische Socket-Thread Erzeugung Netzwerkprogrammierung 2
B Socket Thread handling / Reader init Netzwerkprogrammierung 8
Z Socket Socket-Thread falsch? Netzwerkprogrammierung 5
Helgon Socket Thread Pooling Netzwerkprogrammierung 6
M Was macht Thread, wenn er aus einem "leeren" Inputstream liest ? Netzwerkprogrammierung 5
B callback thread udp Netzwerkprogrammierung 2
D RMI und Thread Netzwerkprogrammierung 4
S Kommunikationsproblem, Thread und manuel Netzwerkprogrammierung 4
U Socket Abhören eines Sockets/Ports in extra Thread Netzwerkprogrammierung 8
K ein Thread pro Stream Netzwerkprogrammierung 2
D Weiterer Thread auf Port 843 horcht Netzwerkprogrammierung 7
D Thread problem Netzwerkprogrammierung 3
S Thread, Daten vom Socket lesen Netzwerkprogrammierung 2
S Thread Transport Netzwerkprogrammierung 6
S Socket Thread in Schleife Netzwerkprogrammierung 4
G Objekte per TCP verschicken + Thread Netzwerkprogrammierung 4
T synchronized mit thread und rückgabe Netzwerkprogrammierung 4
Q Thread und Sockets... Netzwerkprogrammierung 2
2 Class mit ServerSocket erbt von Thread? Netzwerkprogrammierung 3
PAX Outputstream von anderem Thread verwenden lassen Netzwerkprogrammierung 5
C Server mit Multithreading (Thread-Pool) Netzwerkprogrammierung 2
E java.lang.NullPointerException aber nur wenns im Thread läuf Netzwerkprogrammierung 4
F EIN Thread in RMI auf Serverseite Netzwerkprogrammierung 3
G Server Thread beenden Netzwerkprogrammierung 16
T Socket-Thread: Designfrage Netzwerkprogrammierung 14
S Mit Thread arbeitende Maschine Netzwerkprogrammierung 6
T select() ohne NIO - oder wie Worker-Thread sauber beenden? Netzwerkprogrammierung 9
K Selbe Streams mehrfach nutzen (zusätl. Thread) Netzwerkprogrammierung 6
ven000m Thread Frage Netzwerkprogrammierung 11
B Thread.start() (run()) excption Netzwerkprogrammierung 2
M Thread läuft nicht weiter Netzwerkprogrammierung 2
B NullPointerException | Thread Netzwerkprogrammierung 4
U Current thread not owner Netzwerkprogrammierung 3
S readline-thread stoppt vorzeitig Netzwerkprogrammierung 6
J RMI - (RemoteException occurred in server thread) Netzwerkprogrammierung 2
S Webserverprogrammierung: Thread-Beschränkung Netzwerkprogrammierung 2
M Exception in thread "main" java.lang.NoClassDefFou Netzwerkprogrammierung 2
F problem mit thread bzw. netzwerkverbindung! Netzwerkprogrammierung 3
L netzwerk mit thread Netzwerkprogrammierung 3
G RMI thread safe ? Netzwerkprogrammierung 11
A Thread gibt Nachrichten mehrmals aus (Messenger in Java) Netzwerkprogrammierung 3

Ähnliche Java Themen

Neue Themen


Oben