ActiveMQ-Messages übers Netzwerk

inDex

Mitglied
Hallo zusammen,

ich versuche 2 Applikationen über ActiveMQ miteinander kommunizieren zu lassen. Dazu gibt es eine Applikation die den Server darstellt (hier läuft der ActiveMQ Broker auf Port 61616) und eine Applikation die den Client darstellt. Der Server broadcastet in regelmäßigen Abständen einige Messages an ein Topic, welches die Clients abonieren können, um dieses Messages zu erhalten. Zusätzlich verfügt die Server Applikation über einen Consumer, welcher Requests (über eine Queue) entgegen nehmen soll und dort den Clients antwortet. Dies funktioniert auch alles soweit so gut, solange beide Programme auf dem selben Rechner laufen.
Läuft die Client Applikation dann tatsächlich auf einem anderen Rechner, wie es vorgesehen ist, kann diese zwar noch das Topic subscriben und erhält die Nachrichten darin. Allerdings kann der Client keine Requests senden, bzw. diese kommen gar nicht in der Queue oder beim Server/Broker an.

Alles was ich bisher gecheckt und versucht habe:
  • TCP Port 61616 ist auf beiden Rechnern freigegeben (eingehend + ausgehend)
  • Die Rechner lassen sich gegenseitig anpingen
  • Broker kommuniziert auch tatsächlich auf 61616
  • Message kommt nicht in der Queue des Broker an (gesehen über Web-Tool vom Broker)
  • Konfiguration (IP, Port) in beiden Applikationen ist korrekt
  • activemq.xml des Brokers:
    <transportConnectors>
    <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    </transportConnectors>

Da das Szenario perfekt funktioniert wenn es auf dem selben Rechner läuft, vermute ich dass der Code soweit passt. Auch das der Client, wenn er auf einem anderen Rechner läuft die Nachrichten vom Server noch subscriben kann und erhält deutet für mich darauf hin dass die Connection soweit passen muss.

Hat jmd eine Idee ob ich irgendwelche Konfigurationen, Freigaben, etc. übersehen habe oder warum die Messages vom Client nicht in die Queue raus gehen?

Hier noch der Code für die Requests (Auf das wichtigstes gekürzt):

Server:
Java:
package xxx;

import xxx;

public class ActiveMQRequestHandler {

    private static String BROKER_URL = null;
    private static final String REQUEST_QUEUE = "LR_REQUEST_QUEUE";

    private Connection connection;
    private Session session;
    private Destination requestQueue;
    private ExecutorService executorService = Executors.newCachedThreadPool();

    public ActiveMQRequestHandler() {
        BROKER_URL = "tcp://" + Main.getMasterSettings().ACTIVEMQIP + ":" + Main.getMasterSettings().PORT;  // tcp://localhost:61616
        try {
            ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(BROKER_URL);
            connectionFactory.setTrustAllPackages(true);
            connection = connectionFactory.createConnection();
            connection.setClientID("LR_Request_Consumer");
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);  //non transactional
            requestQueue = session.createQueue(REQUEST_QUEUE);
            connection.start();
        } catch (JMSException e) {
            Main.errorLogger.safeExepToTxt(e, "Setting up ActiveMQ Factory for LR Consumer");
            e.printStackTrace();
        }
    }

    public void start() throws JMSException {
        //This Consumer only listens to the RequestQueue
        MessageConsumer requestConsumer = session.createConsumer(requestQueue);
        requestConsumer.setMessageListener(new RequestHandler());
    }

    private class RequestHandler implements MessageListener {
        @Override
        public void onMessage(Message request) {
            executorService.submit(new Worker(request));
        }
    }

    private class Worker implements Runnable {
        private Message requestMsg;

        public Worker(Message request) {
            this.requestMsg = request;
        }

        //Run when new Request is recieved on RequestQueue
        @Override
        public void run() {
            try {
                //Set Up to Reply the Request
                    Destination replyDestoForClient = requestMsg.getJMSReplyTo();
                    MessageProducer replyProducer = session.createProducer(replyDestoForClient);
                    replyProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
                    replyProducer.setTimeToLive(5000);
                //Reply Objects/Messages
                    TextMessage replyMsg = session.createTextMessage();
                    replyMsg.setJMSCorrelationID("Leitrechner");
                    ObjectMessage replyObj = session.createObjectMessage();


//#################################################################################################################
//############ Commands ###########################################################################################
//#################################################################################################################

                if (requestMsg instanceof ObjectMessage){
                    ObjectMessage recObj = (ObjectMessage) requestMsg;
                    RequestMessage requestMessage = (RequestMessage) recObj.getObject();
                    String requestText = requestMessage.getRequestTxt();
                    Object requestObject = requestMessage.getRequestObj();
                    Object requestObject2 = requestMessage.getRequestObj2();
                    replyDestoForClient = requestMsg.getJMSReplyTo();

                    String[] recTxtWords = requestText.split("\\.");
                    String clientID = requestMsg.getJMSCorrelationID();
                    //String clientID = recTxtWords[0];
                    //String target = recTxtWords[1];     // Always = leitrechner
                    String msgType = recTxtWords[2];
                    String subject = recTxtWords[3];
                    Boolean success;

                    if(msgType.equals("command")){
                        switch (subject){
//############ Aufträge ###########################################################################################
                            case "createAuftrag":{
                                Auftrag recAuftrag = (Auftrag) requestObject;
                                //Auftrag erstellen
                                success = Auftrag.createNewAuftrag(recAuftrag);
                                //Antwort mit Success
                                replyMsg.setText(String.valueOf(success));
                                replyProducer.send(replyDestoForClient, replyMsg);
                                System.out.println(requestText + "\t-> Success Feedback: " + success);
                                Main.commLogger.safeToTxt(requestText + "\t-> Success Feedback: " + success);
                                break;
                            }
                    }       
                  
                    //Unkown Subject
                    else {
                        System.out.println(requestText + "\n-> Unknown Subject for a TextMessage (should be a Request Type)!");
                        Main.errorLogger.safeDescripToTxt(requestText + "\n-> Unknown Subject for a TextMessage (should be a Request Type)!");
                    }
                }
                else {
                    System.out.println("Recieved a Message which is not a TextMessage or a ObjectMessage");
                    Main.errorLogger.safeDescripToTxt("Recieved a Message which is not a TextMessage or a ObjectMessage");
                }
            } catch (JMSException e) {
                e.printStackTrace();
                Main.errorLogger.safeExepToTxt(e, "Error in ActiveMQ LR Consumer for incoming Client Messages");
            }
        }
    }

    public void stop() throws JMSException {
        connection.close();
        executorService.shutdown();
    }

}

Client:
Java:
package xxx;

import xxx;
public class ActiveMQRequester {

    private String clientID;
    private ActiveMQConnectionFactory factory;
    private Exception excep = null;
    private final int TIMEOUT = 1500;

    private String command;
    private String commandParam;

    private static String BROKER_URL = null;
    private static final String REQUEST_QUEUE = "LR_REQUEST_QUEUE";
    private String request;
    private String requestParam;

    public ActiveMQRequester(){
        BROKER_URL = "tcp://" + Main.getClientSettings().ACTIVEMQIP + ":" + Main.getClientSettings().PORT; // tcp://192.168.0.2:61616
        try {
            clientID = InetAddress.getLocalHost().getHostName() + "-" + System.getProperty("user.name");
            // Create a connection factory
            factory = new ActiveMQConnectionFactory(BROKER_URL);
            factory.setTrustAllPackages(true);  //Damit Objekte gesendet werden dürfen
        }catch (Exception exClass){
            Main.errorLogger.safeExepToTxt(exClass, "Init ActiveMQ Producer");
        }
    }


    private void sendMessage(MessageType msgType) throws Exception {
        Connection connection = null;
        Session session = null;
        MessageProducer producer = null;
        Destination replyDestForClient = null;
        try {
            //Create connection + session
            connection = factory.createConnection();
            connection.setClientID(clientID);
            connection.start();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            // Create Destination Queue for Command + Producer to Send Command
                Destination lrRequestQueue = session.createQueue(REQUEST_QUEUE);
                producer = session.createProducer(lrRequestQueue);
                producer.setTimeToLive(2500);
                producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
            // Create Temp Response Destination + Consumer for Reply
                replyDestForClient = session.createTemporaryQueue();
                MessageConsumer replyConsumer = session.createConsumer(replyDestForClient);
                Message replyMsg;



            //############################################################
            //######## SEND A COMMAND ####################################
            //############################################################

            if(msgType == MessageType.COMMAND){
                //Create Message for Request
                RequestMessage requestMessage;
                ObjectMessage requestObjMessageToLR = session.createObjectMessage();
                requestObjMessageToLR.setJMSReplyTo(replyDestForClient);
                requestObjMessageToLR.setJMSCorrelationID(clientID);

                switch (command) {

                    case "createAuftrag":{
                        //Send Request to LR
                        requestMessage = new RequestMessage(commandParam, auftragToSend, null);
                        requestObjMessageToLR.setObject(requestMessage);
                        producer.send(lrRequestQueue, requestObjMessageToLR);
                        //Reply from LR
                        replyMsg = replyConsumer.receive(TIMEOUT);
                        if (replyMsg instanceof TextMessage) {
                            if (((TextMessage) replyMsg).getText().equals("true")) {
                                //Successful
                            } else
                                excep = new Exception("Leitrechner Antwort: Auftrag konnte nicht erstellt werden!");
                        } else
                            excep = new Exception("Keine Leitrechner Antwort über den Erfolg!");
                        break;
                    }
                }
            }
        }
        catch (Exception ex) {
            throw ex;
        }finally {
            if(producer!=null)
                producer.close();
            if(session!=null)
                session.close();
            if(connection!=null)
                connection.close();
        }

        //Throw Exception if Command was not successful at LR
        if(excep != null){
            Exception tmpEx = excep;
            excep = null; // wieder zurück setzen
            throw tmpEx;
        }

    }


//##########################################################################
//##################### COMMANDS ###########################################
//##########################################################################

    public void doAuftragAnlegen(Auftrag auftrag) throws Exception {
        command = "createAuftrag";
        commandParam = clientID + ".leitrechner.command." +  "createAuftrag";
        auftragToSend = auftrag;
        sendMessage(MessageType.COMMAND);
    }
 
}
 

LimDul

Top Contributor
Mal probiert vom Client rechner per telnet aufden Broker zuzugreifen? Um zu testen, dass es wirklich kein Firewall/Netzwerk Problem ist?
Ansonsten per netstat auf dem Server schauen, dass er wirklich an die Netzwerk IP bzw. 0.0.0.0 gebunden ist und nicht nur an localhost.
Lässt sich vom Client der Server pingen?

Java:
        BROKER_URL = "tcp://" + Main.getMasterSettings().ACTIVEMQIP + ":" + Main.getMasterSettings().PORT;  // tcp://localhost:61616
Das ist nur, damit der Server Thread sich gegen den Broker verbindet, richtig? Ansonsten wäre Localhost problematisch, wenn damit dre Server gestartet wird.
 

inDex

Mitglied
Das ist nur, damit der Server Thread sich gegen den Broker verbindet, richtig? Ansonsten wäre Localhost problematisch, wenn damit dre Server gestartet wird.
Ja das ist nur, dass die Server Applikation sich quasi mit dem Broker verbindet, welcher aus sicht der Server App auf localhost läuft, um dort ihre Messages zu Queuen bzw. in ein Topic zu spreaden.
  • Der Broker lauscht richtig:
    1683841959330.png
  • Den TCP Port 61616 an Client und Server Rechner habe ich sowohl ausgehend als auch eingehend freigegeben
  • Zu Beginn konnte ich vom Server Rechner (wo auch der Broker läuft) den Client Rechner gar nicht anpingen.
    Nach freigabe von: Datei- und Druckerfreigabe (Echoanforderung - ICMPv4 eingehend / ausgehend)
    am Client hat das allerdings funktioniert.
Nmap-Scan von Client aus an IP/Port des Servers (wo der Broker läuft):

1683843778639.png

Nmap-Scan von Server aus an IP/Port des Clients:
  • Nur Port 61616 freigegeben:
    1683841612127.png
  • Firewall deaktiviert (Dann komischerweise Port-State closed??)
    1683841740041.png
Was mich wundert:
  • Die Nachrichten die der Client nur vom Broker subscribt, bekommt er auch.
    Das heißt eingehende Nachrichten werden vom Client erhalten bzw. die Kommuniaktion zum Broker mit Port 61616
    grundlegend sollte schon einmal funktionieren.
    Ausgehende Nachrichten vom Client, wenn er quasi eine Nachricht beim ActiveMQ Broker enqueuen möchte,
    kommen nicht an, die Queue bleibt unverändert (Sehe ich am Broker-Monitor)
Ausgehende Nachrichten (die nicht funktionieren ) sind doch normalerweise weniger ein Problem als
eingehende Nachrichten (die funktionieren) auf einem Port?

Entweder es klemmt hier noch an irgendwelchen Einstellungen vom Broker, der "fremde" Messages nicht annehmen möchte
oder ich habe tatsächlich noch ein Netzwerk Problem. Unter Windows 10 hatte ich mit solchen Themen bisher nie ein Problem.
Der Client Rechner läuft unter Win 11, gibt es hier vlt noch versteckte Einstellungen die ich übersehen habe.. :rolleyes:

Wäre für jeden weiter Tipp dankbar!! :)
 

LimDul

Top Contributor
Ich würde mal alle Ports ein & ausgehend freigeben und schauen ob es dann geht. Evtl. passieren da Dinge ähnlich wie beim FTP Protokoll, dass über einen weiteren Port die eigentliche Kommunikation stattfindet.

Einfach um Firewall/Netzwerk entweder als Ursache auszumachen (Dann heißt es rausfinden, wie man das entweder ändert oder was man konfigurieren muss) oder um festzustellen, dass es ein anderes Problem ist
 

inDex

Mitglied
Also ich bin jetzt soweit, dass ich ein Netzwerk Thema ausschließen würde. Pingen, Kommunikation, etc. passt eigentlich soweit.
Allerdings verstehe ich das Verhalten hier von ActiveMQ nicht so richtig.

Wenn die Server Applikation, der Broker und der Client alle auf dem selben Rechner und auf Localhost laufen, werden die Nachrichten ganz normal in die Queue eingereiht und von dort gelesen (vom Consumer des Servers).
-> Client macht Request (createAuftrag) in die LR_REQUEST_QUEUE, der Server führt den entsprechenden Algorithmus aus und antwortet dem Server auf die Temporäre Queue die er mitgegeben hat.
-> Messages Enqueed / Message Dequeued +1
-> Passt (Das Bild zeigt die bestehende Queue und die Messages)
1684106509233.png

Wenn Server App. und Broker auf einem Rechner laufen und Client auf einem anderen
, dann sollte der Client seine Nachrichten ebenfalls in die LR_REQUEST_QUEUE einreihen, sodass der Server sie entsprechend wieder lesen kann. Allerdings wird in diesem Szenario "Message Enqueued" nicht um eins erhöht. Das heißt es geht nicht in die Queue. Was ich aber unter "Topics" sehen konnte ist, dass sobald ich die Nachricht am Client abschicke, wird hier ein Topic erzeugt "ActiveMQ.Advisory.Consumer.Queue.ID:DESKTOP...", welches vermutlich für den Consumer des Clients für die Antwort des Servers in der Temporären Queue ist. Auch "ActiveMQ.Advisory.Producer.Queue.LR_REQUEST_QUEUE" wird um eins erhöht.

1684107037506.png

Nachdem dann keine Antwort raus geht und es in den Timeout läuft, kommt bei "....LR_REQUEST" nochmal eins dazu und der Consumver verschwindet (Passt auch, da geclosed wird, s. Code).

1684107384051.png
Das verhalten hier unter "Topics" ist das selbe wie im funktionierenden Szenario wenn alles unter Localhost läuft. Dort wird auch die "ActiveMQ.Advisory.Producer.Queue.LR_REQUEST_QUEUE" um 2 Nachrichten erhöht. Allerdings fehlt dann eben die Nachricht für die eigentliche Queue..

Keine Ahnung, ich hoffe das ist noch irgendwie nachvollziehbar wie ich das hier geschildert habe 😂
Aber ich weis nicht an was es liegt, dass Die Message nicht ankommt wenn sie von einem anderen Rechner geschickt wird...
Erst dachte ich, ich bin evtl. mit den Queues, Temporären Queues, Destinations etc. durcheinander gekommen, aber dann würde es auch nicht laufen wenn alles auf einem Rechner passiert.
 

inDex

Mitglied
Hallo,

sorry dass ich das Thema nochmal aufwärmen muss, aber hänge leider immer noch an dem Problem.
Konnte es allerdings "etwas eingrenzen". Hier nochmmal kurz das Szenario:
  • Rechner A -> ActiveMQ Broker läuft, Server App läuft, alle Ports frei (+ zum Test Firewall deaktiviert)
  • Rechner B -> Client App läuft, alle Ports frei (+ zum Test Firewall deaktiviert)

  • Rechner A published jede Sekunde eine Nachricht in ein Topic X, welches von Rechner B abonniert ist
  • Rechner B published eine Nachricht in ein anderes Topic Y, welches von Rechner A abonniert ist und Rechner A beim Lesen eine Antwort (in TempQueury / an Rechner B) sendet
In meinem Fall kann Rechner B jede Nachricht aus Topic X lesen, allerdings erhält Rechner A die Nachricht von Rechner B aus Topic Y nicht.
Sie kommen zwar bei Rechner A im Broker an (?), ich sehe allerdings im Broker-Manager, dass diese nach der eingestellten Timout-Zeit (im Code) ablaufen (expiren). Laufen beide Applikationen auf einem Rechner funktioniert alles einwandfrei!

Egal welche Szenarien ich versuche mit Broker/Server-App/Client-App tauschen, das Ergebnis ist immer das mein Rechner A die Nachrichten
nicht richtig aus dem Broker raus ziehen kann und diese dann ablaufen. Allerdings habe ich den Port 61616 bereits mit verschiedensten Tools (Telnet, Nmap,...) getestet, Firewall deaktiviert usw. das muss eigentlich passen???
Auch mit den Broker-Settings, Timeout-Zeiten, usw. habe ich bereits in alle Richtung rum gespielt, aber es will einfach nicht klappen.

Könnte jemand mit 2 verschiedenen Win10 Rechnern das mal nachstellen und testen? Ich habe hier ein ZIP
( Link zum .zip Download ) mit beiden Apps (Client + Server) und
dem Broker mit den Einstellungen. Der Port 61616 müsste auf beiden Rechnern vorübergehend freigegeben werden.
Im Falle das alles funktioniert, wäre folgendes zu erwarten:

Server:
1693346003974.png

Client:
1693346037936.png

Ich wäre natürlich auch über jede weitere Idee, warum es nicht funktioniert, dankbar.
Eiere an dem Thema jetzt schon ewig rum :rolleyes:
 

inDex

Mitglied
Wenn der Broker auf Rechner A läuft, habe ich in der App von Rechner B (egal ob Server / Client) die IP von Rechner A angegeben um den Broker zu erreichen.

Auf Rechner A habe ich dann alles getestet:
Localhost
127.0.0.1
0.0.0.0
Eigene IP im Netzwerk
 

inDex

Mitglied
Hast du den Code mal getestet bzw. angeschaut?

Ich verstehe nicht ganz wie du meinst? Der "Server" bzw. die "Server-App" sendet seine Nachrichten im Prinzip
ja auch nur gegen den ActiveMQ Broker. Er lauscht auf keine IP / Ports. Er horcht höchstens ob es in einem Topic / einer Queue
des ActiveMQ Brokers neue Nachrichten für ihn gibt.

Daher muss sich die Server-App mit dem ActiveMQ Broker verbinden. Und diesen erreicht sie in dem Fall auf dem selben Rechner,
also unter Localhost, bzw. der eigenen IP und dem Port von ActiveMQ (61616). Daher denke ich nicht, dass das Problem hier liegt.
 

inDex

Mitglied
Hättest du die Möglichkeit das mal zu testen?
Dann wüsste ich ob das an meinem Netzwerk liegt oder tatsächlich am Code / der Konfiguration etc.
 

Jw456

Top Contributor
Nein ich habe zur Zeit keine Möglichkeit es zutesten.
Ich denke es würde auch nicht laufen.



Für mich müsste bei beiden Apps der consumer besonders clinetID gleich sein.
was es bei dir nicht ist.

Server APP: String ClientID = "LR-Request-Subber";
MessageConsumer consumer = session.createDurableSubscriber(destination, clinetID);

Cleint App : clientID = InetAddress.getLocalHost().getHostName() + "-" + System.getProperty("user.name");

die clinetID ist nicht auf beiden Seiten gleich.

Ob wirklich etwas über das Netzwerk geschickt wird kannst du ja mit sniffen.

PS in beiden Apps musst du die Server IP Adresse benutzen nicht localhost.
 
Zuletzt bearbeitet:

Jw456

Top Contributor
Hallo mal eine kleine Ergenzung zu dem Thema .
Hast du dir mal das Beispiel angesehen was du uns selber unter

"ActiveMQ_Test\apache-activemq-5.18.1\examples\amqp\java\src\main\java\example" mitgegeben hast?

Vor allen wie da die Connection zu ActiveMQ erstellt wird.
Das ist auf Server und Cleint gleich.


Connection connection = factory.createConnection(user, password);
connection.start();


so und nun schaue wie du es machst.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
L ActiveMq - wie kann ich eine Queue löschen? Netzwerkprogrammierung 2
M ActiveMQ Anfänger-Fehler Netzwerkprogrammierung 3
S ActiveMQ, JMS und Datei übertragen Netzwerkprogrammierung 25
Kr0e Java JMS (ActiveMQ) Netzwerkprogrammierung 7
F JMS mit activemq Netzwerkprogrammierung 3
OnDemand JMS Messages wird gecached Netzwerkprogrammierung 2
D Probleme bei mehreren Clients uns Senden von Messages Netzwerkprogrammierung 16
G Parsen von selbstdefinierten Messages Netzwerkprogrammierung 17
O [IRC] Userliste und Server Messages auslesen und anzeigen Netzwerkprogrammierung 4
D Socket-Verbindungen übers Internet Netzwerkprogrammierung 4
I PingPong Spiel übers Netzwerk Netzwerkprogrammierung 1
M Kommunikation übers Internet Netzwerkprogrammierung 9
E Java Server übers Internet erreichen Netzwerkprogrammierung 4
N RMI Einstellungen für "übers Internet" Netzwerkprogrammierung 8
N Gedankenspiel Synchronisation zweier Datenbanktabellen übers Netz Netzwerkprogrammierung 4
H Eine Mac-Adresse übers Internet ermitteln Netzwerkprogrammierung 2
X Password übers Netzwerk schicken jPasswordField Netzwerkprogrammierung 2
Y server client socket verbindung übers internet aufbauen Netzwerkprogrammierung 8
M Socket JFileChooser übers Internet Netzwerkprogrammierung 32
W funktionen übers netzwerk nutzen Netzwerkprogrammierung 4
W browse / durchsuchen übers netz Netzwerkprogrammierung 2
Kr0e Versenden von Daten übers Netzwerk Netzwerkprogrammierung 30
H MySQL übers Netzwerk Netzwerkprogrammierung 9
T Pfadangabe beim kopieren übers Netzwerk Netzwerkprogrammierung 5
M Daten übers Netz verschlüsselt übertragen? Wie? Netzwerkprogrammierung 18
A array übers netzwerk (anfänger) Netzwerkprogrammierung 8
R File chooser übers Netzwerk Netzwerkprogrammierung 3
S Netzwerk übers Internet Netzwerkprogrammierung 30
P Serialialiserte Objekte übers Netzwerk verschicken Netzwerkprogrammierung 9
H Dateigröße übers Internet Netzwerkprogrammierung 3
S Socketverbindung übers WWW Netzwerkprogrammierung 6
G Verzeichnis eines Rechners übers Netzwerk auslesen Netzwerkprogrammierung 5

Ähnliche Java Themen

Neue Themen


Oben