tutorials.de Buch-Aktion 05/2012
Like Tree1Danke
  • 1 Beitrag von Akeshihiro
ERLEDIGT
JA
ANTWORTEN
7
ZUGRIFFE
1044
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Avatar von mccae
    mccae mccae ist offline Senfdazugeber
    Registriert seit
    Dec 2007
    Ort
    Wien
    Beiträge
    226
    Grüße!

    Leider habe ich folgendes Problem und ich weiß auch nicht ob das java oder linux-spezifisch ist:

    Wenn ich einen DatagramSocket erstelle (dabei ist es egal ob ich den parameterlosen konstruktor benutze, oder auf InetAddress und port binde, oder auf eine InetSocketAddress).

    Es ist auch egal ob ich auf die Adresse "127.0.0.1", "localhost", "0.0.0.0", oder auf die IP über die der Server aus dem Internet erreichbar ist binde.

    Folgendes:

    Ich möchte ein Datagrampacket schicken (an localhost, habe es aber auch mit Adressen aus dem Internet probiert).

    Ich bekomme jedoch keine Antwort (timeout).

    Das komische: Unter Windows funktioniert alles perfekt egal ob ich einen lokalen oder einen gameserver im internet ansteuere.

    Auf meinem Linux Server (Debian 5.0 lenny) klappt das ganze jedoch nicht.
    Die entsprechenden Ports sind freigegeben,...

    Hier mal mein Code:

    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    
    package at.co.lipski.twcc.network;
     
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.util.ArrayList;
     
    import at.co.lipski.twcc.logic.Time;
     
    public class TWServerQuery {
        private int timeout;
        private int port;
        private DatagramSocket socko;
        
        public TWServerQuery(){
            port = 8303;
            timeout = 5000;
        }
        
        public TWServerQuery(int port, int timeout, DatagramSocket socko){
            
            if(port>1024){
                this.port = port;
            }
            else{
                this.port = 8303;
            }
            
            if(timeout > 0){
                this.timeout = timeout;
            }
            else{
                this.timeout = 5000;
            }
            this.socko = socko;
        }
        
        public synchronized TeeWorldsStatus doQuery(){
            TeeWorldsStatus s = null;
            try{
                socko.setSoTimeout(timeout);
                byte[] sendData; 
                byte[] receiveData = new byte[1024];      
                String sentence = "ÿÿÿÿÿÿÿÿÿÿgief";
                sendData = sentence.getBytes();
                
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("127.0.0.1"), port);
                
                System.out.println("Sending packet: "+sendPacket.getAddress().toString()+" "+sendPacket.getPort()+" "+sendPacket.getLength());
                socko.send(sendPacket);
                System.out.println("Packet sent!");
                
                DatagramPacket receivePacket = new DatagramPacket(receiveData, 1024);
                
                System.out.println("Receiving,...");
                socko.receive(receivePacket);      
                String modifiedSentence = new String(receivePacket.getData());      
                int index = modifiedSentence.indexOf("info")+4;
                
                String [] infos = modifiedSentence.substring(index).split(""+(char)0);
                 
                String version = infos[0];
                String serverName= infos[1];
                String map = infos[2];
                String gametype = infos[3];
                String percentDone = infos[5];
                String numPlayers = infos[6];
                String maxplayers = infos[7];
                
                ArrayList<String[]> l = new ArrayList<String[]>();
                
                if(infos.length>7){
                    for(int i = 8;i<infos.length;i+=2){
                        String [] array = new String[2];
                        array[0] = infos[i];
                        array[1] = infos[i+1];
                        l.add(array);
                    }
                }
                 
                s = new TeeWorldsStatus();
                 
                s.setVersion(version);
                s.setServerName(serverName);
                s.setMap(map);
                s.setGametype(gametype);
                s.setPercentDone(percentDone);
                s.setNumPlayers(numPlayers);
                s.setMaxplayers(maxplayers);
                s.setPlayers(l);
            }
            
            catch (Exception e){
                boolean truetrue = false;
                boolean isbound = false;
                String addr = "";
                if(socko==null){
                    truetrue = true;
                }
                else{
                    isbound = socko.isBound();
                    addr = ""+socko.getLocalAddress()+socko.getLocalPort();
                }
                System.out.println(Time.genTimeStamp()+"Internal error: "+e.getMessage()+
                        "\n\nIs DatagramSocket null? "+truetrue+"\nIs bound: "+isbound+"\n"+addr+"\n");
                e.printStackTrace();
            }
            return s;
        }
    }

    Nochmal ganz kurz zur Erklärung:

    TeeWorlds ist ein 2D Cartoonshooter.

    Der obige Code soll den Status eines TeeWorlds - servers erfahren der auf 127.0.0.1 läuft. Ich habe es aber auch mit anderen Servern im Internet probiert.

    Unter Windows funktioniert alles ohne Probleme, nur unter Linux kann anscheinend weder unter localhost pakete empfangen, noch welche die von außerhalb kommen,...

    Auf wenn ich probeweise die Firewall ausschalte und alle Ports öffne (ich weiß, böse!) bekomme ich keine Antwort,...

    Entweder landet das gesendete Paket im Nirvana oder ich kann einfach keine Empfangen,...

    Kann mir jemand weiterhelfen?
     

  2. #2
    Avatar von Akeshihiro
    Akeshihiro Akeshihiro ist offline Mitglied Platin
    Registriert seit
    Aug 2008
    Ort
    Kirchlengern (NRW)
    Beiträge
    647
    Bist du dir sicher, dass die Ports freigegeben sind? Bei Linux reicht das nicht, dass du die Ports im Router umleitest. Die meisten Linux-Systeme haben die Angewohnheit alle Ports zu schließen und geben sie erst frei, wenn nach Außen eine Verbindung aufgebaut wird. Das ist auch schön, nur stellst du in deinem Fall keine Verbindung nach Außen her, weil UDP im Gegensatz zu TCP verbindungslos arbeitet. Oder anders gesagt: Du jagst ein Packet raus und es ist dem Sender vollkommen egal, ob es auch ankommt. Folglich erwartet der Sender auch keine Antwort und deswegen wird der entsprechende Port auch nicht aufgemacht.
    mccae bedankt sich. 

  3. #3
    Avatar von mccae
    mccae mccae ist offline Senfdazugeber
    Registriert seit
    Dec 2007
    Ort
    Wien
    Beiträge
    226
    Zitat Zitat von Akeshihiro Beitrag anzeigen
    Bist du dir sicher, dass die Ports freigegeben sind? Bei Linux reicht das nicht, dass du die Ports im Router umleitest. Die meisten Linux-Systeme haben die Angewohnheit alle Ports zu schließen und geben sie erst frei, wenn nach Außen eine Verbindung aufgebaut wird. Das ist auch schön, nur stellst du in deinem Fall keine Verbindung nach Außen her, weil UDP im Gegensatz zu TCP verbindungslos arbeitet. Oder anders gesagt: Du jagst ein Packet raus und es ist dem Sender vollkommen egal, ob es auch ankommt. Folglich erwartet der Sender auch keine Antwort und deswegen wird der entsprechende Port auch nicht aufgemacht.
    Die Ports sind frei, und nicht Java-Programme haben auch keine Probleme mit UDP,...

    Mit "Ports freigegeben" habe ich ja unter anderem die iptables gemeint
    Geändert von mccae (16.07.09 um 14:12 Uhr) Grund: Ergänzungen,...
     

  4. #4
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo,

    Könnte es vielleicht daran liegen?
    DatagramPacket receivePacket = new DatagramPacket(receiveData, 1024);
    (Bzw. daran das ich Windows / Linux unterschiedlich Verhalten... )
    Was passiert denn wenn du
    Code java:
    1
    
    DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
    verwendest?


    folgendes funktioniert bei mir unter Ubuntu Linux 9.04 als normaler User einwandfrei :
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    
    package de.tutorials;
     
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.nio.ByteBuffer;
    import java.util.Date;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
     
    public class UPDClientServerExample {
     
        final static int port = 4711;
     
        /**
         * @param args
         */
        public static void main(String[] args) {
            
            ExecutorService
             executorService = Executors.newCachedThreadPool();
            
            executorService.execute(new Runnable() {
                public void run() {
                    try {
                        DatagramSocket socket = new DatagramSocket(port);
     
                        byte[] data = new byte[13];
                        while (true) {
                            DatagramPacket packet = new DatagramPacket(data,
                                    data.length);
                            socket.receive(packet);
     
                            ByteBuffer buffer = ByteBuffer.wrap(data);
        
                            
                            int sequence = buffer.getInt();
                            byte action = buffer.get();
                            long timestamp = buffer.getLong();
                            
                            System.out.println(Thread.currentThread()
                                    + " received: S:" + sequence + " A:" + action + " T:" + new Date(timestamp));
                            
                            if(action == (byte)-1){
                                break;
                            }
                        }
                        
                        socket.close();
     
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
     
                }
            });
     
            executorService.execute(new Runnable() {
                public void run() {
                    try {
                        DatagramSocket socket = new DatagramSocket();
     
                        for  (int i = 0; i<= 10;i++) {
                            DatagramPacket packet = createPacket(i, i == 10 ? (byte)-1 : (byte)0);
                            System.out.println(Thread.currentThread()
                                    + " sending: " + packet);
                            socket.send(packet);
                            TimeUnit.SECONDS.sleep(1);
                        }
     
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
            
            executorService.shutdown();
     
        }
     
        private static DatagramPacket createPacket(int sequence, byte command) throws Exception {
            
            //payload = 4 bytes sequence, 1 byte command,  8 bytes timestamp
            
            byte[] payload = new byte[13];
            ByteBuffer buffer = ByteBuffer.wrap(payload);
            
            buffer.putInt(sequence);
            buffer.put(command);
            buffer.putLong(System.currentTimeMillis());
            
            DatagramPacket packet = new DatagramPacket(payload, payload.length,    InetAddress.getLocalHost(), port);
            return packet;
        }
     
    }

    Ausgabe:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@39d99a4d
    Thread[pool-1-thread-1,5,main] received: S:0 A:0 T:Thu Jul 16 20:13:45 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@9e97676
    Thread[pool-1-thread-1,5,main] received: S:1 A:0 T:Thu Jul 16 20:13:46 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@3e60420f
    Thread[pool-1-thread-1,5,main] received: S:2 A:0 T:Thu Jul 16 20:13:47 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@219106c7
    Thread[pool-1-thread-1,5,main] received: S:3 A:0 T:Thu Jul 16 20:13:48 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@13d4c61c
    Thread[pool-1-thread-1,5,main] received: S:4 A:0 T:Thu Jul 16 20:13:49 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@761a626f
    Thread[pool-1-thread-1,5,main] received: S:5 A:0 T:Thu Jul 16 20:13:50 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@3e34a1fc
    Thread[pool-1-thread-1,5,main] received: S:6 A:0 T:Thu Jul 16 20:13:51 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@7176c74b
    Thread[pool-1-thread-1,5,main] received: S:7 A:0 T:Thu Jul 16 20:13:52 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@2d16471f
    Thread[pool-1-thread-1,5,main] received: S:8 A:0 T:Thu Jul 16 20:13:53 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@11975b59
    Thread[pool-1-thread-1,5,main] received: S:9 A:0 T:Thu Jul 16 20:13:54 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@67ee3914
    Thread[pool-1-thread-1,5,main] received: S:10 A:-1 T:Thu Jul 16 20:13:55 CEST 2009

    Gruß Tom
     
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  5. #5
    Avatar von mccae
    mccae mccae ist offline Senfdazugeber
    Registriert seit
    Dec 2007
    Ort
    Wien
    Beiträge
    226
    Zitat Zitat von Thomas Darimont Beitrag anzeigen
    Hallo,

    Könnte es vielleicht daran liegen?

    (Bzw. daran das ich Windows / Linux unterschiedlich Verhalten... )
    Was passiert denn wenn du
    Code java:
    1
    
    DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
    verwendest?
    Leider passiert gar nichts,...

    Ich weiß ja, dass receiveData eine Länge von 1024 hat. Weshalb sollte ich receiveData.length verwenden?

    Das ganze ist total myteriös,...
     

  6. #6
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo,

    Ich weiß ja, dass receiveData eine Länge von 1024 hat. Weshalb sollte ich receiveData.length verwenden?
    Okay hatte ich übersehen. Trotzdem wenn du die größe von receiveData Änderst musst du die andere Stelle auch immer mitanpassen... insofern ist receiveData.length schon besser.

    Funktioniert mein kleines UDP Beispiel?

    Bekommst du ne Exception oder bleibt das Ganze einfach nur Hängen? Mach mal einen ThreadDump.
    Unter Linux kannst du via Ctrl + \ gleichzeitig in der Konsole einen ThreadDump erzeugen lassen.

    Eine andere Möglichkeit wäre ein kill -QUIT an den entsprechenden JVM Prozess zu senden.

    Wenn du den hast kannst du genau sehen wo der Thread innerhalb von receive... wartet und damit eventuell
    Rückschlüsse auf die Fehlerursache ziehen.

    Gruß Tom
     
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  7. #7
    Avatar von mccae
    mccae mccae ist offline Senfdazugeber
    Registriert seit
    Dec 2007
    Ort
    Wien
    Beiträge
    226
    Zitat Zitat von Thomas Darimont Beitrag anzeigen
    Hallo,


    Okay hatte ich übersehen. Trotzdem wenn du die größe von receiveData Änderst musst du die andere Stelle auch immer mitanpassen... insofern ist receiveData.length schon besser.

    Funktioniert mein kleines UDP Beispiel?

    Bekommst du ne Exception oder bleibt das Ganze einfach nur Hängen? Mach mal einen ThreadDump.
    Unter Linux kannst du via Ctrl + \ gleichzeitig in der Konsole einen ThreadDump erzeugen lassen.

    Eine andere Möglichkeit wäre ein kill -QUIT an den entsprechenden JVM Prozess zu senden.

    Wenn du den hast kannst du genau sehen wo der Thread innerhalb von receive... wartet und damit eventuell
    Rückschlüsse auf die Fehlerursache ziehen.

    Gruß Tom
    Hm,...
    Das ganze scheint zu funktionieren,...

    Hier der Output:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    vadmin55:~# java -jar test.jar
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@156ee8e
    Thread[pool-1-thread-1,5,main] received: S:0 A:0 T:Fri Jul 17 16:40:43 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@e0e1c6
    Thread[pool-1-thread-1,5,main] received: S:1 A:0 T:Fri Jul 17 16:40:44 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@6ca1c
    Thread[pool-1-thread-1,5,main] received: S:2 A:0 T:Fri Jul 17 16:40:45 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@1bf216a
    Thread[pool-1-thread-1,5,main] received: S:3 A:0 T:Fri Jul 17 16:40:46 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@12ac982
    Thread[pool-1-thread-1,5,main] received: S:4 A:0 T:Fri Jul 17 16:40:47 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@c20e24
    Thread[pool-1-thread-1,5,main] received: S:5 A:0 T:Fri Jul 17 16:40:48 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@2e7263
    Thread[pool-1-thread-1,5,main] received: S:6 A:0 T:Fri Jul 17 16:40:49 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@157f0dc
    Thread[pool-1-thread-1,5,main] received: S:7 A:0 T:Fri Jul 17 16:40:50 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@863399
    Thread[pool-1-thread-1,5,main] received: S:8 A:0 T:Fri Jul 17 16:40:51 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@a59698
    Thread[pool-1-thread-1,5,main] received: S:9 A:0 T:Fri Jul 17 16:40:52 CEST 2009
    Thread[pool-1-thread-2,5,main] sending: java.net.DatagramPacket@141d683
    Thread[pool-1-thread-1,5,main] received: S:10 A:-1 T:Fri Jul 17 16:40:53 CEST 2009


    Also wird es wohl ein Problem mit der Linux-version des Programms sein, welches antworten soll,...
    Geändert von mccae (17.07.09 um 17:03 Uhr)
     

  8. #8
    Avatar von mccae
    mccae mccae ist offline Senfdazugeber
    Registriert seit
    Dec 2007
    Ort
    Wien
    Beiträge
    226
    Bitte entschuldigt, dass ich meinen Thread wieder aus der Versenkung hole, aber ich glaube jetzt den Grund der Fehlfunktion gefunden zu haben....

    Wer den Thread gelesen hat, weiss, dass ich ein UDP paket an ein lokales tool schicke und dieses nicht antwortet (aber nur unter Linux).

    Vor kurzem habe ich herausgefunden, dass Linux Maschinen einen anderen Zeichensatz benutzen.
    Der Inhalt des UDP-pakets ist hardcoded und ist "ÿÿÿÿÿÿÿÿÿÿgief".

    Mein Linux Server benutzt den Zeichensatz: US-ASCII, und meine Windows Maschine den Windows Latin 1 Zeichensatz.

    Mir ist aufgefallen dass das Zeichen 'ÿ' nicht im US-ASCII Satz vorkommt.
    Liegt es möglicherweise daran?

    Werden gehardcodete Zeichen mit dem Zeichensatz des lokalen Systems encoded?

    Wenn ja, gibt es eine Möglichkeit das default-Charset während der Laufzeit zu definieren?
     

Ähnliche Themen

  1. Java Programm als Dienst unter Linux Debian ausführen
    Von marcel_m im Forum Linux & Unix
    Antworten: 25
    Letzter Beitrag: 19.03.08, 11:09
  2. JSP Seiten laufen nicht unter Tomcat 5.5 - Linux Debian System
    Von filigrani im Forum Enterprise Java (JEE, J2EE, Spring & Co.)
    Antworten: 6
    Letzter Beitrag: 27.02.08, 15:03
  3. Hilfe dringend bei Email-Server unter Linux Debian !
    Von Symbiontx im Forum Linux & Unix
    Antworten: 1
    Letzter Beitrag: 04.04.05, 20:52
  4. Javascript unter Linux (Debian)
    Von Marshallbbw im Forum Javascript & Ajax
    Antworten: 6
    Letzter Beitrag: 21.03.05, 14:24