Socket Nachricht von TCP-Client an Server schicken

Bitte aktiviere JavaScript!
Hallo, liebes Java Forum,
ich habe ein Programm mit GUI geschrieben, auf dem man Zahlen in ein Feld eintragen kann. Dann gibt es einen senden-Button, der die eingegebenen Zahlen an einen TCP-Client senden soll.
Hier der Code, mit dem ich die sendData-Methode der TCPClient-Klasse aufrufe:
Java:
TCPClient tcpclient = new TCPClient();
//                        IP        Port 
tcpclient.sendData("192.168.106.1", 8000, text);
Mein Problem ist nun, dass ich zwar eine Verbindung aufbauen kann, aber der text nicht versendet wird

Hier der Code der sendData-Methode aus der TCPClient-Klasse(das meiste davon hab ich aus dem Netz):
Java:
public boolean sendData(String IP, int port, String text) throws Exception {
        try {
            InputStream txtStream = new ByteArrayInputStream(text.getBytes());
            BufferedReader inFromUser = new BufferedReader(new InputStreamReader(txtStream));
            Socket clientSocket = new Socket(IP, port);   
            System.out.println("Verbindung aufgebaut");
            DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
            BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            text = inFromUser.readLine();
            outToServer.writeBytes(text + 'n');
            clientSocket.close();
            System.out.println("Verbindung getrennt");
            
            return true;
        } catch (Exception e1) {
            e1.printStackTrace();
            return false;
        }
    }
Weiß irgendjemand, wie ich das möglichst einfach hinbekomme?
Ich mein, ich bin ja verbunden, also IP und Port stimmen, nur den Text will er nicht senden... sollte also kein großer Schritt mehr sein. Oder?

Vielen Dank im Voraus, für eure Hilfe!
MFG
Morris F.
 
A

Anzeige




Vielleicht hilft dir unser Kurs hier weiter —> (hier klicken)
Also ich würde vermuten, dass dein in den Socket schreiben gecacht wird und durch das sofortige close() wird das nicht mehr geschrieben.

Also ich würde daher ein flush() Aufruf auf dem Stream machen.
Aber socket hat auch shutdownOutput, das stellt auch sicher, dass die Daten, die bisher geschrieben wurden, wirklich gesendet werden ehe dann der Kanal im Handshake geschlossen wird ... das hört sich auch nicht schlecht an.

Und Dein Code sieht stark nach https://systembash.com/a-simple-java-tcp-server-and-tcp-client/ aus. Da ist das kein Problem, denn nach dem Schreiben kommt ein Lesen. Da wartet also der Client auf den Server... und der Server sendet ja erst nach dem Empfangen der Nachricht ....
 
Also ich würde daher ein flush() Aufruf auf dem Stream machen.
Aber socket hat auch shutdownOutput, das stellt auch sicher, dass die Daten, die bisher geschrieben wurden, wirklich gesendet werden ehe dann der Kanal im Handshake geschlossen wird ... das hört sich auch nicht schlecht an.
Hallo kneitzel,
danke für deine Antwort!
leider bin ich noch nicht so bewandert auf dem Gebiet und verstehe nur Bahnhofo_O
Wäre also toll, wenn du mir mal ein Beispielprogramm oder besser noch mein Programm umgeschrieben zeigen könntest, damit ich mir das ein bisschen besser vorstellen kann.
MFG
Morris F.
 
Direkt im Code bedeutet das, was ich gesagt habe:

Java:
public boolean sendData(String IP, int port, String text) throws Exception {
        try {
            InputStream txtStream = new ByteArrayInputStream(text.getBytes());
            BufferedReader inFromUser = new BufferedReader(new InputStreamReader(txtStream));
            Socket clientSocket = new Socket(IP, port);   
            System.out.println("Verbindung aufgebaut");
            DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
            BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            text = inFromUser.readLine();
            outToServer.writeBytes(text + 'n');
            outToServer.flush(); // (1)
            // clientSocket.shutdownOutput(); // (2)
            clientSocket.close();
            System.out.println("Verbindung getrennt");
            
            return true;
        } catch (Exception e1) {
            e1.printStackTrace();
            return false;
        }
    }
(1) ist der flush() Aufruf beim Stream. Streams können (teilweise) Daten zwischenpuffern. Und mit flush wird ein solcher Puffer denn geleert. Bildlich sind Streams sozusagen sowas wie Rohre. Die kann man auch aneinander stecken (DataOutputStream kommt auf den OutputStram vom Socket). Und manche haben halt auch eine Art Waschbecken dran. Und da kann dann Wasser gesammelt werden und nur wenn im Waschbecken genug Wasser drin ist, wird der Stöpsel mal kurz gezogen...
Und was ich vermute ist: Du hast halt so ein Rohr mit Waschbecken. Das hast Du erzeugt, Wasser rein getan und danach sofort weggeschmissen (Close Aufruf). Durch das flush() hast Du jetzt ein "Lass das Wasser abfließen, bis das Waschbecken leer ist" mit eingebaut.

(2) Hier wird der Stream auch schon geschlossen für Transfers. Aber erst nachdem alle Anstehenden Daten gesendet wurden. Ich vermute, dass (1) die Lösung sein dürfte und dass (2) nicht notwendig ist. Daher erst einmal auskommentiert.
 
Ich habe noch etwas festgestellt:
ich habe einen sehr seltsamen loop im Output vom Server(siehe Bild)
11873
Woran kann das leigen?
Ich habe es mal durchdebugt und gesehen, dass dieser beginn/ende loop beim clientSocket.close(); entsteht. Is das ein Fehler vom Server oder liegts am Code?
 
Zuletzt bearbeitet:
Dazu kann ich nichts sagen, da ich keine Ahnung habe, was Du da überhaupt machst. Alles, was wir bisher nur sehen, ist eine kleine Funktion sendData.
 
(1) ist der flush() Aufruf beim Stream. Streams können (teilweise) Daten zwischenpuffern. Und mit flush wird ein solcher Puffer denn geleert. Bildlich sind Streams sozusagen sowas wie Rohre. Die kann man auch aneinander stecken (DataOutputStream kommt auf den OutputStram vom Socket). Und manche haben halt auch eine Art Waschbecken dran. Und da kann dann Wasser gesammelt werden und nur wenn im Waschbecken genug Wasser drin ist, wird der Stöpsel mal kurz gezogen...
Und was ich vermute ist: Du hast halt so ein Rohr mit Waschbecken. Das hast Du erzeugt, Wasser rein getan und danach sofort weggeschmissen (Close Aufruf). Durch das flush() hast Du jetzt ein "Lass das Wasser abfließen, bis das Waschbecken leer ist" mit eingebaut.

(2) Hier wird der Stream auch schon geschlossen für Transfers. Aber erst nachdem alle Anstehenden Daten gesendet wurden. Ich vermute, dass (1) die Lösung sein dürfte und dass (2) nicht notwendig ist. Daher erst einmal auskommentiert.
Vielen Dank, für die tolle Erklärung! Hat mir sehr beim Verständnis gehlofen xD
Leider kommt immernoch kein Text beim Server an und er hat diesen komischen beginn/ende loop...
 
Dazu kann ich nichts sagen, da ich keine Ahnung habe, was Du da überhaupt machst. Alles, was wir bisher nur sehen, ist eine kleine Funktion sendData.
Ich habe ein kleines Client-Server Programm. Da mein Java Programm in dem Fall der Client ist, nutze ich nur die Server-funktion.
das Ganze schaut folgendermaßen aus:
11874
in meinem Java-Programm habe ich den selben Port und die selbe IP eingetragen und das verbinden klappt einwandfrei
11875
unten im Log steht ja Connected und Execute.

wenn ich vom Client des Programms eine Nachricht an den Server vom Programm schicke, steht das auch alles da und die Nachricht vom Client erscheint im Log des Servers.

wenn jetzt aber mein Java Programm der Client ist, Connectet er, erhält keine Nachricht, sondern geht dann in diesen beginn/ende loop.

Ich hoffe, das war irgendwie verständlich
 
Sorry, ich habe mich unklar ausgedrückt: Ich meinte damit Wissen über den Code selbst. Was machst Du auf der Server Seite? Was machst Du genau auf der Client Seite? Also mit Code. Nur dann können wir Dich auf Probleme im Code aufmerksam machen.
 
Ich habe meinen Quellcode ein bisschen angepasst und verschönert aber habe das selbe Problem:
Java:
public boolean sendData(String IP, int port, String text) throws Exception {
        try {
            InputStream txtStream = new ByteArrayInputStream(text.getBytes());
            BufferedReader inFromUser = new BufferedReader(new InputStreamReader(txtStream));
            Socket clientSocket = new Socket(IP, port);   
            System.out.println("Verbindung aufgebaut");
            DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
            text = inFromUser.readLine();
            outToServer.writeBytes(text);
            outToServer.writeUTF(text);
            outToServer.flush();
            clientSocket.shutdownOutput();
            System.out.println("Daten gesendet");
            clientSocket.close();
            System.out.println("Verbindung getrennt");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
 
Sorry, ich habe mich unklar ausgedrückt: Ich meinte damit Wissen über den Code selbst. Was machst Du auf der Server Seite? Was machst Du genau auf der Client Seite? Also mit Code. Nur dann können wir Dich auf Probleme im Code aufmerksam machen.
ich habe das Client-Server-Programm nicht selbst programmiert, also weiss ich nicht, was da im Hintergrund im Code abgeht...
ich weiss nur, dass ich IP und Port einstelle und auf Open klicke... dann lauscht der Server auf dem angegebenen Port.
mein Client is ja mein Java Programm, da hab ich ja jetzt nochma den aktuellen Code gepostet.

im Grunde will ich nur den String text vom Client an den Server schicken, das is alles.
 
Deine Aussage zu dem Server Part besagt fast nichts. Wenn Du Dich zu einem Server verbinden willst, musst Du mehr wissen als nur den Port. Ist es TCP oder UDP wäre das Erste. Ok, die Meldungen besagen etwas von TCP...
Aber was erwartet der Server an Eingabe? Welches Protokoll spricht er?

Deine Routine verbindet sich und sendet den Text. Das jetzt sogar zwei mal!

Ich habe das einfach einmal auf die Schnelle mit zwei kleinen Klassen geprüft:
a) Server.java:
Java:
package tcptest;

import java.io.*;
import java.net.*;

public class Server {
    public static void main(String argv[]) throws Exception {
        String clientSentence;
        ServerSocket welcomeSocket = new ServerSocket(6789);

        while (true) {
            Socket connectionSocket = welcomeSocket.accept();
            System.out.println("Verbindung eingegangen von " + connectionSocket.getInetAddress().toString());
            BufferedReader inFromClient =
                    new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
            DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
            clientSentence = inFromClient.readLine();
            System.out.println("Received: " + clientSentence);
        }
    }
}
Wie man erkennen kann: Mein Server erwartet eine ganze Zeile (readLine, d.h. es muss ein Zeilenumbruch am Ende kommen!)
(Sowas ist wichtig, denn wenn ich einen langen Text sende, dann muss ja der Server wissen, wann die Nachricht zuende ist. Ich könnte aber auch ein anderes Protokoll schreiben. Ich könnte in x Bytes erst eine Größe angeben und dann diese Anzahl an Bytes lesen (Also dieses content length das man evtl. kennt).

Und dann der Client. Hab jetzt auch noch einmal getestet: Ich brauchte kein flush und kein shutdownOutput. (Letzteres hätte mich auch etwas gewundert). Deine Funktion braucht auch kein throws Exeption wenn du doch ehh alle fängst ...
Java:
package tcptest;

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

public class Client {
    public static boolean sendData(String IP, int port, String text) {
        try {
            InputStream txtStream = new ByteArrayInputStream(text.getBytes());
            BufferedReader inFromUser = new BufferedReader(new InputStreamReader(txtStream));
            Socket clientSocket = new Socket(IP, port);
            System.out.println("Verbindung aufgebaut");
            DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
            text = inFromUser.readLine();
            outToServer.writeBytes(text + '\n');
//            outToServer.flush();
//            clientSocket.shutdownOutput();
            System.out.println("Daten gesendet");
            clientSocket.close();
            System.out.println("Verbindung getrennt");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static void main (String[] args) {
        sendData("127.0.0.1", 6789, "test");
    }
}
Was man hier jetzt aber noch erkennt: Ich füge ein Zeilenumbruch ans Ende. Denn ohne den würde readLine ja nicht die Zeile einlesen.
(Und jetzt verstehe ich auch, was das + 'n' in dem code ursprünglich war. Das hatte ich bei Dir gesehen und auch auf der Seite von der Du es wohl auch hattest ... irgend was hat da das \ gefressen :)
 
Danke nochmal für die Hilfe!
ich hab jetzt das ganze über linux mit netcat als TCP-Server geteste und es funst.
Das Client-Server Programm von mir war wohl ein bisschen Panne...

MFG
Morris
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben