2016-08-09 15 views
4

Ich starte ein Java-Programm während meiner Raspberry Startup (die Raspbian aktiviert). Ich benutzte die /etc/rc.local Datei, um dies zu tun und es funktioniert einwandfrei (Ich versuchte auch /etc/init.d/ Lösung, aber ich bevorzuge die andere). Ich starte mein raspbian direkt im Konsolenmodus, so kann ich die Ausgabe meines Programms sehen.Bind Ausnahme nur beim Start beim Start [Raspbian]

Mein Problem ist: Manuell starten meine App, es funktioniert gut. Wird automatisch beim Booten gestartet, löst eine Bind-Ausnahme aus: Die angeforderte Adresse kann nicht zugewiesen werden.

Programm starten

Auf der /etc/rc.local Datei, schrieb ich diese Zeile. Es startet ein Skript, das mein .jar-Programm startet.

#! /bin/sh -e 
# 
# rc.local 
# 
# [...] 

# Print the IP address 
_IP=$(hostname -I) || true 
if [ "$_IP" ]; then 
    printf "My IP address is %s\n" "$_IP" 
fi 
# \/ Added \/ 
/home/pi/Documents/DinnerTimePi/startApp 

exit 0 

Mein startApp Skript enthält:

#! /bin/sh 

cd /home/pi/Documents/DinnerTimePi/ 

date >> testStart.txt #Only for checking it runs at launch 
java -jar DinnerTimeServer.jar 

exit 0 

Standardprogramm Ausgabe

Server initialised at : 192.168.1.35 address and : 35150 port. 
_ #(Waiting for client to connect) 

Java Programmteil

Mein Java-Programm ist ein Serversocket ein paar Sachen zu tun, es funktioniert richtig auch.

public class TimeServer { 
    //Instance of class : can have only one server at a time 
    static private TimeServer instance; 
    //Default values 
    static private int port = 35150; 
    static private String host = "192.168.1.35"; //Adapt for your network, give a fix IP by DHCP 
    //Variables 
    private ServerSocket server = null; 


    protected TimeServer(String pHost, int pPort){ // <- I'm running this constructor with the default values above 
     list = new LinkedList<ClientProcessor>(); 
     host = pHost; // 192.168.1.135 
     port = pPort; // 35150 
     try { 
      // \/ Line 57 on my code (see stack trace) \/ 
      server = new ServerSocket(port, 10, InetAddress.getByName(host)); 
     } catch (BindException bind){ 
      bind.printStackTrace(); //Here is the problem !! 
      System.exit(1); 
     } catch (UnknownHostException hoste) { 
      hoste.printStackTrace(); 
     } catch (IOException ioe) { 
      ioe.printStackTrace(); 
     } 
    } 

Wie Sie sehen können, habe ich die IP-Adresse 192.168.1.35, die statische auf mein Modem ist, und es funktioniert gut. Ich vermute, der Port wurde während des Bootens verwendet, so Ich versuchte verschiedene Ports, wie 6543 und 35150. Aber es tut das gleiche: manuell arbeiten, aber nicht während des automatischen Startvorgangs.

Stapelüberwachung

Dies ist, was ich als Ausgabe sehen, wenn meine Raspberry booten.

[...] 
[ OK ] Reached target Network is Online. 
     Starting LSB: Start NTP deamon... 
[ OK ] Started LSB: Start NTP deamon. 
java.net.BindException: Can't assign requested address 
    at java.net.PlainSocketImpl.socketBind(Native Method) 
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387) 
    at java.net.ServerSocket.bind(ServerSocket.java:375) 
    at java.net.ServerSocket.<init>(ServerSocket.java:237) 
    at server.TimeServer.<init>(TimeServer.java:57) 
    at server.TimeServer.getInstance(TimeServer.java:32) 
    at server.Main_Server.main(Main_Server.java:12) 
[ OK ] Started /etc/rc.local Compatibility. 
     Starting Terminate Plymouth Boot Screen... 
[...] 

Das, was ich nicht verstehe, ist, warum auch mein Programm funktioniert es selbst startet, und es funktioniert nicht, wenn das System es starten. Es gibt keine Wurzel braucht für mein Programm.

Ich hoffe, es ist klar, zögern Sie nicht, wenn Sie weitere Informationen benötigen.

Vielen Dank für Ihre Hilfe!:)

(Überprüfen Sie das gesamte Programm aus, wenn auf github benötigt, Auto-Start Zweig)

+0

Sie verwenden InetAddress.getByName (Host), die Namensauflösung funktioniert (und vielleicht ist es nicht an dem Punkt, wenn Sie die Funktion aufrufen), aber Sie kennen bereits die IP-Adresse, also InetAddress.forString (String ipString) wäre angemessener. – grahamj42

+0

Ich weiß nicht, wo du deine Methode gesehen hast, laut der Dokumentation existiert sie nicht ^^ " Es klappt gut so, auch wenn ich dir zustimme, gebe ich den Hostnamen aber nicht direkt an IP java sucht nach. – Kapcash

Antwort

2

Werfen Sie die Linien des Konstrukteurs in eine spezifische Funktion:

protected boolean initThis(String pHost, int pPort) { 
    list = new LinkedList<ClientProcessor>(); 
    host = pHost; // 192.168.1.135 
    port = pPort; // 35150 
    try { 
     // \/ Line 57 on my code (see stack trace) \/ 
     server = new ServerSocket(port, 10, InetAddress.getByName(host)); 
    } catch (BindException bind){ 
     bind.printStackTrace(); //Here is the problem !! 
     return false; 
    } catch (UnknownHostException hoste) { 
     hoste.printStackTrace(); 
     return false; // Change this to true if you want it to stop here 
    } catch (IOException ioe) { 
     ioe.printStackTrace(); 
     return false; // Change to true to stop here 
    } 
    return true; 
} 

Jetzt in Ihrem Konstruktor:

protected TimeServer(String pHost, int pPort) { 
    while(!initThis(pHost, pPort)) 
     Thread.sleep(500); // Wait 0.5 secs before retry 
} 

Dies wird so oft wiederholt, bis es funktioniert.

+0

Ich kann es nicht glauben.Ich dachte nie eine Sekunde, es wäre das Problem, weil es perfekt manuell funktioniert.Diese Lösung ist so einfach! Vielen Dank, Sie sparen mich. – Kapcash

+0

Gern geschehen Schön, dass dir das weiterhilft. Danke fürs berichten. – xdevs23