UDP Problem

Status
Nicht offen für weitere Antworten.

Big_Daddi

Mitglied
Hi hi,

ich habe folgendes Problem. Und zwar versuche ich vergebens eine UDP datenübertragung herzustellen. Jedoch hab ich dabei "leichte" Probleme. Ich habe folgenden Quellcode auch schon versucht:
Java:
import java.net.DatagramPacket;
import java.net.DatagramSocket;

class WriteServer {
  public static void main(String args[]) throws Exception {
    int clientPort = 999;

    int buffer_size = 1024;

    byte buffer[] = new byte[buffer_size];
    DatagramSocket ds = new DatagramSocket(clientPort);
    while (true) {
      DatagramPacket p = new DatagramPacket(buffer, buffer.length);
      ds.receive(p);
      System.out.println(new String(p.getData(), 0, p.getLength()));
    }
  }
}

Jedoch wenn ich das Programm laufen lasse, macht er mir eine Endlosschleife und in der Console kommt nur "null" in rot und das die ganze zeit!
Vielleicht ist das nicht der richtige Port??? Ich bin ratlos. Hab schon nen Portscan durchgeführt und da hat er mir gesagt Port 88 und 548 sind offen. Aber mit denen geht es auch nicht!
Kann es auch daran liegen dass es ein MAC ist und kein Windows Rechner?? Sollte aber normalerweise ja nichts ausmachen oder?

Den Sendeteil der funktioniert, da sagt auch meine Firewall dass sie etwas an eine IP-Adresse durchgelassen hat. Jedoch der Empfang will nicht so ganz!

Sorry für die vielen Fragen aber ich noch ein wenig ein Neuling!

Danke schon mal im Voraus!

Gruß
 
Zuletzt bearbeitet:
soweit ich weiß, kann man doch als User (in *nix-Systemen) Ports > 1000 (oder war es sogar die wunderschöne Zahl 1024) öffnen.
 
Hey

Also ich habe es auch mal ausgeführt, bei mir bleibt es bei der receive() Methode Stehen, was ja auch richtig ist, weil die so lange blockiert bis daten ankommen. Meine frage ist, du hast hier eine Server geschieben der auf dem Port 999 lauscht, du brauchst natürlich auch einen client der sich zu diesen Port verbindet, wo ist der oder was für eine Service steckt dahinter.

Ich habe mal eine Kleines UDP Server - Client beispiel gemacht:

UDPServer.java

Java:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPServer {

	public static void main(String[] args) throws IOException {
		int port = 999;
		int buffer_size = 1024;

		byte buffer[] = new byte[buffer_size];
		DatagramSocket ds = new DatagramSocket(port);
		while (true) {
			DatagramPacket p = new DatagramPacket(buffer, buffer.length);
			ds.receive(p);
			System.out.println(new String(p.getData(), 0, p.getLength()));
		}

	}

}

UDPClient.java
Java:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Date;

public class UDPClient {

	public static void main(String[] args) throws IOException {
		int port = 999;
		InetAddress address = InetAddress.getByName("localhost");

		DatagramSocket socket = new DatagramSocket();

		for (int i = 0; i < 10; i++) {

			String date = new Date().toString();
			DatagramPacket packet = new DatagramPacket(date.getBytes(), date.getBytes().length, address, port);

			packet.setData(date.getBytes());
			socket.send(packet);

			sleep(1000);
		}

		socket.close();
	}

	private static void sleep(long millis) {
		try {
			Thread.sleep(millis);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Ich hoffe es Hielf dir!!!
 
Also sprich ich muss zuerst wissen an welchen Port das Gerät die Daten schickt??
Ich glaub jetzt hats gerappelt. 🙂

Wenn ich jetzt zb auf port 1500 stell dann bleibt er stehen.
Jetzt mal sehn was mir die leute sagen, wohin die die daten senden.

DANKESCHON
 
Zuletzt bearbeitet:
Halli Hallo,

jetzt bin ichs schon wieder! Und zwar hänge ich jetzt an folgendem Problem:

ich sende einen String an ein Gerät, das funktioniert auch. Dann sendet das Gerät etwas zurück, das funktioniert auch. Hab ich mit Wireshark getestet. Es kommt auch das zurück was zurück kommen soll.
Jedoch bleibt mein Java-Programm also Eclipse vor udpreceive.receive(data); stehen
Hier der Codeausschnitt
Java:
byte buffer [] = new byte [100];
DatagramSocket udpreceive = new DatagramSocket();
DatagramPacket data = new DatagramPacket(buffer, buffer.length);
udpreceive.receive(data);
System.out.println(new String(data.getData(),0,data.getLength()));

Danke schon mal!
 
Bleibt er "vor" receive hängen oder in der Zeile.
Das erste wäre wirklich sehr komisch. Im zweiten Fall könnte es daran liegen, dass du deinem Socket keinen port gegeben hast.
 
Guten Morgen,

@Geee:
Also ich hab einfach folgendes versucht. vor der receive Zeile einfach nen System.out.println() rein gesetzt, das geht auch soweit. Aber wenn ich es danach setze dann schreibt er mir es nicht aus, eben wie den String! Wireshark sagt dass die Daten an Port 49156 rein kommen und von Port 65363 kommen. Wie gebe ich denn eine Socket frei???

ja mein ankommendes Paket hat derzeit 30 bytes laut Wireshark. und das stimmt auch. Das ganze läuft so ich schicke eine Zeichenkette an das Gerät, das Gerät verarbeitet diese und schaut welche daten es mir schicken muss. Als Bsp ich schicke IPADDRESS dann sendet das Gerät mir eben seine ip-adresse zurück oder name oder sonstige variablen!
Wie gesagt es kommt auch an aber das java kann irgendwie nicht verarbeiten??????
???:L???:L???:L
 
Zuletzt bearbeitet:
Dei Größe ist doch total egal. Hauptsache es kommt was. Wenn es mehr als 100 Bytes sind, wird abgeschnitten.
Wenn du dir sicher bist, dass dein Gerät auf 65363 zurücksendet, dann ergänze oben die Zeile:
Java:
DatagramSocket udpreceive = new DatagramSocket();
durch
Java:
DatagramSocket udpreceive = new DatagramSocket(65363);

Verstehe diese "Gerätverbindung" irgendwie immer noch nicht. Musst du überhaupt einen neuen Socket anlegen? Kann man nicht einfach den, der schon an das Gerät gesendet hat, verwenden? (Wie gesagt UDP-Erfahrungen was vor allem die Umsetzung angeht, sind bei mir nicht so ausgeprägt 😀 )
 
Ja des stimmt schon, mir geht es auch nicht um die Größe. sondern ich möchte einfach nur mal dass mein Programm was mach! 🙂

Das mit dem Port im DatagramSocket hab ich auch schon versucht!
Des is ne gute Frage ob ich den gleichen nehmen kann oder nicht. Ich habs jetzt auch mal mit dem gleichen versucht aber der geht auch nicht wirklich.

Kann es vlt. mit etwas außerhalb von Eclipse zu tun haben. Also mein LittleSnitch sagt, dass die Verbindungen von und zu der IP von dem Gerät frei sind also erlaubt sind!!!
 
So..hier nochmal ein einfaches Beispiel mit Hin- und Rückweg:
Dein "Gerät"
Java:
public class UDPMaster {

    public static void main(String[] args) throws IOException {
        byte[] code = new byte[100];
        DatagramSocket readerSocket = new DatagramSocket(1234);
        DatagramSocket senderSocket = new DatagramSocket();
        
        DatagramPacket packet = new DatagramPacket(code,code.length);
        readerSocket.receive(packet);
        
        
        System.out.println("got order: " + new String(code));
        String answer = "answer";
        
        packet = new DatagramPacket(answer.getBytes(),answer.getBytes().length, InetAddress.getLocalHost(), 1235);
        senderSocket.send(packet);
        
    }
    
}
Dein Rechner:
Java:
public class UDPSlave {
    
    public static void main(String[] args) throws IOException {
        byte[] incomingInformation = new byte[100];
        byte[] order = new String("do something").getBytes();
        InetAddress address = InetAddress.getLocalHost();
        DatagramSocket senderSocket = new DatagramSocket();
        DatagramSocket readerSocket = new DatagramSocket(1235);
        DatagramPacket packet = new DatagramPacket(order, order.length,address, 1234);
        senderSocket.send(packet);
        packet = new DatagramPacket(incomingInformation, incomingInformation.length);
        readerSocket.receive(packet);
        System.out.println("Got information: " + new String(packet.getData()));
    }

}
Ist nur auf die Schnelle getippt, aber funzt eigentlich. Musst nur noch die Ports anpassen. Soweit ich das jetzt getestet habe, geht ein Re-Use des Sockets bei UDP nicht (wg. dem nicht vorhandenen Zustand?).
Fänd es interessant zu erfahren, ob mein oben geschriebenes Beispiel so "UDP-konform" ist.
 
Da ist ja eigentlich das selbe wie ich habe. ;(

Naja das Problem mit dem Incoming Port ist dies, dass der sich anscheinend immer ändert. Also so sieht es zumindest im Wireshark aus. Somit kann ich ja den Port im Socket nicht angeben!
 
so.update:
Client:
Java:
public class UDPSlave {
    
    public static void main(String[] args) throws IOException {
        byte[] incomingInformation = new byte[100];
        byte[] order = new String("do something").getBytes();
        InetAddress address = InetAddress.getLocalHost();
        DatagramSocket senderSocket = new DatagramSocket();
        DatagramPacket packet = new DatagramPacket(order, order.length,address, 1234);
        senderSocket.send(packet);
        packet = new DatagramPacket(incomingInformation, incomingInformation.length);
        senderSocket.receive(packet);
        System.out.println("Got information: " + new String(packet.getData()));
    }

}
Gerät:
Java:
public class UDPMaster {

    public static void main(String[] args) throws IOException {
        byte[] code = new byte[100];
        DatagramSocket readerSocket = new DatagramSocket(1234);
        DatagramSocket senderSocket = new DatagramSocket();
        
        DatagramPacket packet = new DatagramPacket(code,code.length);
        readerSocket.receive(packet);
        
        
        System.out.println("got order: " + new String(code));
        String answer = "answer";
        
        packet = new DatagramPacket(answer.getBytes(),answer.getBytes().length, packet.getAddress(), packet.getPort());
        senderSocket.send(packet);
        
    }
    
}
 
Du machst doch gar nix mit dem Gerät...Nimm einfach nur den Slave code, mit dem passenden Port auf dem dein Gerät horcht und pack deine IPNACHRICHT drauf.
 
Dann zeig ich nochmal die Ausschnitte auf, weil evtl. hast du die kleine Änderung nicht gesehen:
Java:
DatagramSocket senderSocket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(order, order.length, GERAET_IP , GERAET_PORT);
dann kannst du
Java:
// befehl senden
senderSocket.send(packet);
// antwort empfangen
byte[] incomingInformation = new byte[100];
packet = new DatagramPacket(incomingInformation, incomingInformation.length);
senderSocket.receive(packet);
Da ist dir der Port, von dem das Gerät zu deinem Rechner kommt total egal. Du musst eben nur wissen, auf welchem port du das Gerät ansprechen musst am Anfang (das klappt ja schon, hast du ja gesagt).
Du kannst das alles hintereinander weg so reinschreiben.
 
Zuletzt bearbeitet:
Also das gleiche hab ich jetzt mal versucht -> ohne erfolg!!!!

Wie gesagt send(); klappt aber receive(); bleibt er einfach stehen und wartet auf ein einkommendes Paket. Laut Wireshark kommt das ja auch aber das Javaprogramm frisst es nicht!

Die receive() Methode frägt doch alle eingehenden ports ab oder??? Muss ich die Ports bei meinem PC irgendwie öffnen oder so????
 
Du könntest ja einfach mal bei senderSocket.receive einen breakpoint setzen und schauen, ob der localPort (also, der durch den die Verbindung auf Clientseite aufgemacht wurde) der gleiche ist, den du auch in Wireshark siehst.
 
Gute Idee! ...

senderSocket.getLocalPort();

Damit bekomm ich den gleichen Port der auch in WireShark steht.

ich hab jetzt mal senderSocket.isConnected(); gemacht, aber da liefert er mir false zurück???????????
 
der Socket ist ja auch nur gebunden, wenn "was passiert". Der liefert bei mir auch immer false zurück. Würde wohl nur während des Sendens / Empfangens true sein.
Also nun ist das Problem wirklich sehr komisch. Wenn du da am Empfang hängst und wireshark sagt, dass da was kommt, dann muss es doch auch eingelesen werden. Ich bin verwirrt.
 
Zuletzt bearbeitet:
ich hab jetzt mal mit .connect(Addr., port); das nochmal versucht, bleibt aber trotzdem an der stelle stehen!

Ich verzeweifel langsam aber sicher! 🙂
 
Das brauchst du ja auch gar nicht.
Rezept für den einfachen Fall eines Befehls vom Client:

Zutaten:
1 DatagramSocket
1 InetAddress vom Server
1 Port vom Server
2 DatagramPackets (eins zum Senden und eins für den Empfang)
2 byte[] (Empfang / Senden)
Zubereitung:
1. Man nehme das eine byte[] und packe seinen Befehl hinein.
2. Man bereite das zweite byte[] mit einer beliebigen Größe vor.
3. Einstellen der InetAddress auf das Ziel.
4. Erstellen Sie nun einen DatagramSocket OHNE parameter.
5. Zum Senden des Befehls sollten Sie nun ein DatagramPacket-Objekt erstellen, dem Sie die Nachricht, Länge, InetAddress und Port mit auf dem Weg geben.
6. Die vorgefertigten Stücke mit Hilfe des DatagramSockets rausschicken
--- Nun kommt der komplizierterer Teil. Einige Köche scheitern an dieser Stelle 😀 ---
7. Um eine Antwort zu erhalten, sollten sie nun ein zweiten DatagramPacket-Objekt erstellen, welches nur die Informationen enthält, in welches (vorbereitete) byte[] es schreiben soll und wieviel maximal beigefügt werden darf
8. Nun machen wir erneut Gebrauch von unserem DatagramSocket, mit dem wir schon erfolgreich unsere Nachricht rausgesendet haben. Mit Hilfe des gerade erzeugten DatagramPackets wird er in den LeseModus gesetzt.
9. Über das Ergebnis freuen.

Ist jetzt gerade mal irgendwie n bissl untechnischer geworden, aber überprüf bitte, ob du auch alles so gemacht hast.
Wenns noch immer net klappt, kannst du mir gerne deinen Source auch mal als PM schicken (gekürzte, ausführbare aber nicht funktionierende Version).
Oder bau dir selber einmal nach dem o.g. MasterBeispiel ein "Gerät-Mock"
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben