Socket UDP Hole Punching?

seejay

Aktives Mitglied
Hallo,

ich bin gerade dabei mich etwas in die Netzwerkprogrammierung von Java einzuarbeiten. Mit TCP habe ich es bereits geschafft ein 4 gewinnt über das Netzwerk spielbar zu machen. Da ich aber niemanden zumuten will/kann, dass er für so einfache games seine Firewall öffnet, wollte ich es mit UDP und dem Hole Punching probieren.
An sich ist doch die Sache, dass ich einfach ganz viele Pakete an eine Adresse schicke und dadurch der Router Pakete von dort zu mir weiterleitet.
Deshalb habe ich folgendes Testprogram geschrieben
Klasse als Thread die immer nur sendet
Java:
        while (true)
        {
            try {
                SocketAddress addr = new InetSocketAddress( this.ip,  9876 );
                DatagramSocket clientSocket = new DatagramSocket();
                byte[] sendData = new byte[1024];
                sendData = "Sehr komisch".getBytes();
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, addr);
                clientSocket.send(sendPacket);
                clientSocket.close();
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                Logger.getLogger(UDPSend.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(UDPSend.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
und ein weitere Thread der nur horcht und wenn er was gefunden hat in eine Textarea schreibt
Java:
        try {
            DatagramSocket serverSocket = new DatagramSocket(9876);
            byte[] receiveData = new byte[1024];
            while (true)
            {
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                serverSocket.receive(receivePacket);
                String sentence = new String( receivePacket.getData());
                view.addMessage(sentence);

            }
        } catch (IOException ex) {
            Logger.getLogger(UDPReceive.class.getName()).log(Level.SEVERE, null, ex);
        }

Leider funktioniert es nicht. Ich habe es so getestet:
A) 1PC mit Router <-> B) 1 PC ohne Router
B bekommt die Pakete von A, aber A keine von B. Deshalb denke ich mal, dass der Router diese nicht weiterleitet.

Habe ich irgendetwas falsch gemacht oder woran könnte es noch liegen?

Danke und Gruß
seejay
 

ice-breaker

Top Contributor
sowohl B als auch A müssen senden und empfangen, hast du das gemacht? (du hast nicht genau beschrieben wer alles welche Aufgaben macht)
 

seejay

Aktives Mitglied
bei beiden ist das Progamm gelaufen, welches die 2 Threads startet (senden und empfangen) mit jeweils der IP Adresse des anderem als Ziel und dem gleichen Port.
 

Empire Phoenix

Top Contributor
An dieser stelle frage ich mich wie du es dann geschafft hast beide tdatagramsockets auf beiden seiten auf den SELBEN port gleichzeitig zu binden? Das müsstest du nämlich tun weil UDP holepunching sender und empfänger auf den selben port braucht.

es macht übrigens keine probleme auf den selben udp socket einen thread im recive stecken zu haben und einen anderen send benutzen zu lassen.

Zudem warum startst du den socket am client ständig neu???? lass den offen, zuletzt sei noch geagt das close bei einem verbindungslosen protokol wie udp so ziemlich garnichts macht.
 

seejay

Aktives Mitglied
An dieser stelle frage ich mich wie du es dann geschafft hast beide tdatagramsockets auf beiden seiten auf den SELBEN port gleichzeitig zu binden? Das müsstest du nämlich tun weil UDP holepunching sender und empfänger auf den selben port braucht.
verstehe ich gerade nicht so genau. Habe einfach beim Erzeugen der DatagramSockets jeweils den selben Port angegeben

es macht übrigens keine probleme auf den selben udp socket einen thread im recive stecken zu haben und einen anderen send benutzen zu lassen.

Zudem warum startst du den socket am client ständig neu???? lass den offen, zuletzt sei noch geagt das close bei einem verbindungslosen protokol wie udp so ziemlich garnichts macht.
da hast du recht. Habe es jetzt mal etwas umgebaut.
Gui
Java:
        try {
            ta_result.setText("");
            DatagramSocket socket = new DatagramSocket(9876);
            UDPReceive rec = new UDPReceive(socket,this);
            UDPSend send = new UDPSend(socket,this,tf_ip.getText());
            Thread t1 = new Thread(send);
            t1.start();
            Thread t2 = new Thread(rec);
            t2.start();
        } catch (IOException ex) {
            Logger.getLogger(UDPTestView.class.getName()).log(Level.SEVERE, null, ex);
        }

sender
Java:
    public UDPSend(DatagramSocket socket,UDPTestView view,String ip)
    {
        this.ip = ip;
        this.clientSocket = socket;
        this.view = view;
    }
    public void run() {
        while (true)
        {
            try {
                SocketAddress addr = new InetSocketAddress( this.ip,  9876 );
                byte[] sendData = new byte[1024];
                sendData = "Sehr komisch".getBytes();
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, addr);
                clientSocket.send(sendPacket);
                Thread.sleep(500);
            } catch (Exception ex) {
                Logger.getLogger(UDPSend.class.getName()).log(Level.SEVERE, null, ex);
                view.addMessage(ex.getMessage());
            }
        }
    }

empfang
Java:
    public UDPReceive(DatagramSocket socket, UDPTestView view)
    {
        this.serverSocket = socket;
        this.view = view;
    }
    public void run() {
        try {         
            byte[] receiveData = new byte[1024];
            while (true)
            {
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                serverSocket.receive(receivePacket);
                String sentence = new String( receivePacket.getData());
                view.addMessage(sentence);
            }
        } catch (IOException ex) {
            Logger.getLogger(UDPReceive.class.getName()).log(Level.SEVERE, null, ex);
            view.addMessage(ex.getMessage());
        }
    }

jetzt müsste es doch aber funktionieren? Kann es leider erst heute abend ausprobieren, wenn wieder ein freund online ist
 

Empire Phoenix

Top Contributor
Hm tendenzeil gebe ich dir ja recht mit den neuen DatagramSocket, aber was wenn ein Packet genau dazwischen eintrifft?

Funktionieren sollte das in etwa so, habe sowas ähnliches schon selber einmal benutzt.
 

Ähnliche Java Themen


Oben