【问题标题】:Bind Exception only when launched at boot [Raspbian]仅在启动时启动时绑定异常 [Raspbian]
【发布时间】:2016-08-09 12:10:12
【问题描述】:

我在 Raspberry 启动期间启动了一个 java 程序(它正在打开 Raspbian)。 我使用/etc/rc.local 文件来执行此操作,并且它工作正常(我也尝试了 /etc/init.d/ 解决方案,但我更喜欢另一个)。 我直接在控制台模式下启动我的 raspbian,这样我可以看到我的程序的输出。

我的问题是:手动启动我的应用程序,效果很好。在启动时自动启动,它会引发绑定异常:无法分配请求的地址。

启动程序

/etc/rc.local 文件中,我写了这一行。它会启动一个脚本来启动我的 .jar 程序。

#! /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

我的 startApp 脚本包含:

#! /bin/sh

cd /home/pi/Documents/DinnerTimePi/

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

exit 0

正常程序输出

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

Java程序部分

我的 Java 程序是一个做一些事情的 ServerSocket,它也可以正常工作。

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();
        } 
    }

如您所见,我在调制解调器上使用了 静态 IP 地址 192.168.1.35,它运行良好。 我认为该端口是在启动过程中使用的,所以我尝试了不同的端口,如 6543 和 35150。但它的作用相同:手动工作,但在自动启动期间不工作。

堆栈跟踪

这是我在启动 Raspberry 时看到的输出。

[...]
[ 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...
[...]

我不明白的是为什么我的程序自己启动它运行良好,而系统启动它时却不行。 我的程序没有 root 需求

我希望它很清楚,如果您需要更多信息,请不要犹豫。

感谢您的帮助! :)

(如果需要,请在github自动启动分支上查看整个程序)

【问题讨论】:

  • 您正在使用 InetAddress.getByName(host) ,它需要名称解析才能工作(也许在您调用该函数时还没有),但您已经知道 IP 地址,所以 InetAddress。 forString(String ipString) 会更合适。
  • 不知道你在哪里看到你的方法,根据文档,是不存在的^^" 这样很好用,就算同意你,我也不给主机名,但直接是 java 正在搜索的 IP。

标签: java raspberry-pi serversocket boot


【解决方案1】:

将构造函数的行放入特定的函数中:

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;
}

现在在你的构造函数中:

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

这会重试很多次,直到成功为止。

【讨论】:

  • 我不敢相信。我从没想过这会是问题,因为它可以完美地手动运行。这个解决方案很简单!非常感谢,你救了我。
  • 不客气。很高兴这对您有所帮助。感谢您的报告。
猜你喜欢
  • 2015-10-25
  • 1970-01-01
  • 2017-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-31
  • 1970-01-01
  • 2014-06-16
相关资源
最近更新 更多