在Linux(Ubuntu 18.04)上设置用Java编写的DHCP服务器时遇到的问题。

huangapple go评论85阅读模式
英文:

Problems setting up DCHP server written in java on linux (Ubuntu 18.04)

问题

我是新手使用Linux,对网络也不太熟悉,所以可能在过程中犯了一些愚蠢的错误。

这里是我正在尝试设置的“网络”的当前“拓扑结构”。

所以,我正在Linux机器上设置DHCP服务器,据我所知,DHCP的工作方式是这样的(从服务器的角度来看)...它接收客户端广播的DHCPDISCOVER,然后通过广播向客户端提供来自分配的“池”中的地址(DHCPOFFER),然后客户端请求地址(DHCPREQUEST),最后服务器确认(DHCPACK或如果出现错误则为NACK)。目前我卡在了DHCPOFFER步骤上,因为当我连接Linux笔记本电脑(服务器)与我的Windows笔记本电脑(客户端)时,它收到了一个DHCPDISCOVER,并在尝试广播DHCPOFFER时抛出了异常。

我目前正在使用这个配置进行网络设置,但到目前为止,我尝试了多种变化

....DHCPMessage.BROADCAST_ADDR = InetAddress.getByName("255.255.255.255")....
....DHCPMessage.CLIENT_PORT = 68....

try {
        byte[] data = back.msgToByteArr();
        socket.setBroadcast(true);
        
        var pack = new DatagramPacket(data, data.length,
                DHCPMessage.BROADCAST_ADDR, DHCPMessage.CLIENT_PORT);
        
        var arr = new byte[]{1};
        var pack1 = new DatagramPacket(arr, arr.length,
                DHCPMessage.BROADCAST_ADDR, DHCPMessage.CLIENT_PORT);
        
        var pack2 = new DatagramPacket(arr, arr.length,
                InetAddress.getByName("192.168.0.255"), DHCPMessage.CLIENT_PORT);
        
        // 在下一行无论尝试发送pack、pack1还是pack2(或者我迄今为止尝试的许多其他变化),都会引发“java.io.IOException:网络不可达”的错误
        socket.send(pack2);

    } catch (IOException e) {
        return;
    }

现在,这些只是我最后尝试发送的一些,成功接收DHCPDISCOVER后

pack  <<-- 真正的DHCPOFFER消息, 
pack1 <<-- 我进行的其他尝试之一,只发送一个字节  
pack2 <<-- 另一次尝试,我尝试考虑掩码进行广播

还有一件值得一提的事情,就是一旦我在服务器笔记本电脑上打开了WiFi(现在以太网和WiFi都已连接),DHCPOFFER就可以正常发送,但现在我再也不会从客户端收到DHCPREQUEST了,它一直卡在DHCPDISCOVER / DHCPOFFER上,循环几次。

最后一件事是,在服务器笔记本电脑上打开WiFi时,当我用手机连接时,整个通信经过DHCPDISCOVER->DHCSPOFFER->DHCPREQUEST->DHCPACK(在此时我停止在手机上访问互联网,但我猜这是因为分配的私有IP不适用于公共域名)。对我来说,这是最不重要的事情,因为我想让以太网连接的网络工作,而不是WiFi网络,但也许它携带了一些重要的信息。

英文:

I'm new to linux and kind of new to networking so I might have made some stupid mistake along the way.

This is current "topology" of the "network" I'm trying to setup.

So, I am setting up the DHCP server on linux machine and afaik, the DHCP works like this (from the point of the server) .. it receives DHCPDISCOVER which client has broadcasted then it offers a client an address from the assigned "pool" (DHCPOFFER) also by broadcast, then client requests the address (DHCPREQUEST) and finally server acknowledges (DHCPACK or NACK if some err). Currently I am stuck at the DHCPOFFER step, because when I connect the linux laptop (server) with my windows laptop (client), it receives a DHCPDISCOVER and throws an exception when trying to broadcast DHCPOFFER.

I'm currently using this configuration for the network, but so far I've tried multiple variations

....DHCPMessage.BROADCAST_ADDR = InetAddress.getByName(&quot;255.255.255.255&quot;)....
....DHCPMessage.CLIENT_PORT = 68....

try {
        byte[] data = back.msgToByteArr();
        socket.setBroadcast(true);
        
        
        var pack = new DatagramPacket(data, data.length,
                DHCPMessage.BROADCAST_ADDR, DHCPMessage.CLIENT_PORT);
        
        var arr = new byte[]{1};
        var pack1 = new DatagramPacket(arr, arr.length,
                DHCPMessage.BROADCAST_ADDR, DHCPMessage.CLIENT_PORT);
        
        var pack2 = new DatagramPacket(arr, arr.length,
                InetAddress.getByName(&quot;192.168.0.255&quot;), DHCPMessage.CLIENT_PORT);
        
        // after next line &quot;java.io.IOException: Network is unreachable&quot; is raised
        // regardless of trying to send pack, pack1 or pack2 (or many other variations I&#39;ve tried so far)
        socket.send(pack2);

    } catch (IOException e) {
        return;
    }

Now, these are just a few of the last ones I've tried sending, after successfully receiving DHCPDISCOVER

pack  &lt;&lt;-- the real DHCPOFFER message, 
pack1 &lt;&lt;-- one of other attempts I&#39;ve made, with just one byte sending  
pack2 &lt;&lt;-- another attempt where I tried to broadcast keeping in mind the mask

One more thing that might be worth mentioning is that once I turn wifi on on the server laptop (now both eth and wifi are up), the DHCPOFFER goes through, but now I never get DHCPREQUEST from client, its stuck on DHCPDISCOVER / DHCPOFFER looping few times.

Last thing is that while the wifi is on on the server laptop, when I connect with my phone, the whole communication goes through DHCPDISCOVER->DHCSPOFFER->DHCPREQUEST->DHCPACK (at which point I stop having internet access on my phone, but I'm guessing that's since the assigned private IP is not good for the public domain). This is the least important thing for me since I want to make the ethernet connected network work, not the wifi one, but maybe it carries some important info.

答案1

得分: 0

Ok,所以...尽管我仍然不能完全解释为什么广播会抛出所说的异常,但是!我找到了一种方法使一切都正常工作。原来,不需要更改代码,

而是需要更改Linux上的网络设置。

我正在发布我是如何修复它的,如果有一些像我一样不幸的人遇到类似的问题。此外,确实有一些有知识的人,其中一些人可能会花时间解释发生了什么。

我的猜测:(请注意,这只是一个猜测)服务器笔记本电脑没有与网络通信的方式,正在寻找IP本身 - (即从另一个DHCP读取)因此,当它自动分配一个地址时,该地址对所需的网络来说不合适,因此问题出现在网络设置中(可能传播到套接字),而不是代码本身(或接收部分 - 255.255.255.255广播)。

英文:

Ok so... even though I am still not 100% able to explain WHY the broadcast was throwing the said exception, BUT! I managed to find a way to make everything work. Turns out, there was no need for change in the code

but rather the setup of the network on linux itself.

I'm posting how I fixed it if some unlucky soul as myself stumbles upon something similar. Also, there sure are some knowledgeable people out there and some of them might take the time to explain what was happening.

MY GUESS: (and mind, its just a guess) the server laptop didn't have a way to communicate on network and was searching for the IP itself - (read - from another DHCP) so when it was auto assigned an address, that address wasn't good for the needed network, therefore the problem was in the network settings (possibly propagating to sockets) rather than in the code itself (or the receiving part - 255.255.255.255 BROADCAST).

huangapple
  • 本文由 发表于 2020年7月28日 19:41:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/63133303.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定