detecting devices connected to my network - java

I need Java code to detect current connected devices to my network.
I tried the following idea :
- for all possible addresses check if this address is connected ( 254 loop )
- to speed up this process I created a thread for each check to make them run in parallel
Is there any way more efficient ??

Well there are lots of ways of detecting networked devices and you give no specifics on the nature of your situation.
The simplest (and most simplistic) approach I can think of would be to ping the broadcast address of your IP network and then consult the system's ARP table.
Unfortunately I have no particular strategy for accessing the ARP table from Java to suggest.

Related

How two Java network servers can share one IP

I want to create Java Network servers which share one IP address. Something like the Piranha cluster:
Is there any solution similar to this?
P.S They have to work as a cluster. If one server is down the second one should handle the traffic.
Well the obvious solution would be to try to build your Java servers behind the Piranha layer; i.e. implement the application services on "real server 1", "real server 2", etcetera in Java
I'm pretty sure that you can't implement a Piranha-like solution in (pure) Java. The IP level load balancing is implemented in the network stack in the OS kernel (I think) of the "director". That rules out (pure) Java for two reasons:
It is impractical to put Java code inside the kernel.
To do it in user space in Java would entail using native code to read and write raw network packets. That is not possible in pure Java.
Besides, the chances are that you'd get better network throughput if the director layer was not implemented in Java, pure or otherwise.
Of course, there are other ways to do load balancing as well ...
Just create your standalone tcp/ip servers to listen on different ports (and ofcourse the IP address would be same as this is your requirement)

How to switch between networks from a Java application?

Is it possible to disconnect from one wi-fi network and connect to another network programatically using java?
My java application makes request to twitter using twitter4j. I can make only 350 requests per hour from a particular IP address. Now I'm sleeping for an hour before continuing my requests. But I have two Wi-Fi networks to connect to.
So when the limit exceeds and I get an exception, if I can switch between the networks, I can double the amount of work done. Is it possible in java?
It's only possible in java because java can call native code. You would need to implement this with native code in C or C++.
You could execute from your Java program an external program that would disconnect and reconnect (if you get an IP via DHCP).
Doesn't seem like the solution lies in the program, though. More in the way it's being used... or what it's being used (or shouldn't be used) for.

How do I distinguish if two IPs belong to the same computer?

We have a master program and agents (both) on the customer side on different computers. The network configuration can be any type (we don't know). The agents connect to the master program and currently we only can get the IP and computer name as information. How do I distinguish if two IPs belong to the same computer?
Computers may have more than one ethernet cards.
Thanks.
There is no way to tell just by looking at the IP addresses.
Some computers have unique identifiers, but you would need JNI to access them and your code would be very platform-specific. It might be a better idea to generate a GUID and write it to a file in a temp folder on the machine. Then, all instances of the software that run on that machine would read the same GUID and can provide this data to the server when a connection is made.
You can modify the agents to send the MAC(s) of the machines in question. Beyond that, you can't really determine if they are the same.
You say you're getting the computer name - can't you de-duplicate based on that value?
From across a network, and given only an IP address, you can't tell. The way NAT works, and the fact that today's laptops and wireless devices often hop from network to network throughout the day, all you see is the public-facing IP address of that machine, which is very likely shared across a group, or entire organization of machines.
Unless you modify the agent application to also include a unique identifier (such as MAC address - which even then only tells you it's a unique NIC, not necessarily a unique machine if machines have multiple NICs), you're out of luck. You can't determine uniqueness from the IP address alone.
Not sure what your use case is, but if it's for banning/tracing actions within the application, then it's better to require some kind of unique identifier for the machine to access the system (such as a username) so you know that you can ban/trace a single instance of the app, or a single user logged into any instance of the app, rather than trying to solve that kind of a problem through IP addresses.
You could create a service in its machine that will expose a unique identifier. You could then call this service using different IPs as the host name and compare the values.

Java SE find the adjacent PCs or Devices on the network

I have seen applications that can detect adjacent networks and desktops and devices attached to them. They can also know the computer/device name that is attached within 30 seconds.
Shall I try runtime.execute ping and net view command to do it, for I find them fast.
How can I capture the output as a result from these commands?
I tried sockets but they are time consuming.. only advantage, that I can also know that they have application installed (in which I created socket, enabling this communication).
Regards
Time-Outs in the initialization of Socket are useful, but you cannot have each connection connected within less than 300 Milli-seconds. On the server side also there is a timeout implementation. There is one sided communication in both. Multi-threading will help.

Java IOException: No buffer space available while sending UDP packets on Linux

I have a third party component which tries to send too many UDP messages to too many separate addresses in a certain situation. This is a burst which happens when the software is started and the situation is temporary. I'm actually not sure is it the plain amount of the messages or the fact that each of them go to a separate IP address.
Anyway, changing the underlying protocol or the problematic component is not an option, so I'm looking for a workaround. The StackTrace looks like this:
java.io.IOException: No buffer space available
at java.net.PlainDatagramSocketImpl.send(Native Method)
at java.net.DatagramSocket.send(DatagramSocket.java:612)
This issue occurs (at least) with Java versions 1.6.0_13 and 1.6.0_10 and Linux versions Ubuntu 9.04 and RHEL 4.6.
Are there any Java system properties or Linux configuration tweaks which might help?
I've finally determined what the issue is. The Java IOException is misleading since it is "No buffer space available" but the root issue is that the local ARP table has been filled. On Linux, the default ARP table lookup is 1024 (files /proc/sys/net/ipv4/neigh/default/gc_thresh1, /proc/sys/net/ipv4/neigh/default/gc_thresh2, /proc/sys/net/ipv4/neigh/default/gc_thresh3).
What was happening in my case (and I assume your case), is that your Java code is sending out UDP packets from an IP address that is in the same subnet as your destination addresses. When this is the case, the Linux machine will perform an ARP lookup to translate the IP address into the hardware MAC address. Since you are blasting out packets to many different IPs the local ARP table fills up quickly, hits 1024, and that is when the Java exception is thrown.
The solution is simple, either increase the limit by editing the files I mentioned earlier, or move your server into a different subnet than your destination addresses, which then causes the Linux box to no longer perform neighbor ARP lookups (instead will be handled by a router on the network).
When sending lots of messages, especially over gigabit ethernet in Linux, the stock parameters for your kernel are usually not optimal. You can increase the Linux kernel buffer size for networking through:
echo 1048576 > /proc/sys/net/core/wmem_max
echo 1048576 > /proc/sys/net/core/wmem_default
echo 1048576 > /proc/sys/net/core/rmem_max
echo 1048576 > /proc/sys/net/core/rmem_default
As root.
Or use sysctl
sysctl -w net.core.rmem_max=8388608
There are tons of network options
See Linux Network Tuning by IBM
and More tuning information
Might be a bit complicated but as I know, Java uses the SPI1 pattern for the network sub-library. This allows you to change the implementation used for various network operations. If you use OpenJDK then you could gain some hints how and what to wrap with your implementation. Then, in your implementation you slow down the I/O with some sleeps for example.
Or, just for fun, you could override the default DatagramSocket with your modified implementation. Have the same package name for it and - as I know - it will take precedence over the default JRE class. At least this method worked for me on some buggy 3rd party library.
Edit:
1Service Provider Interface is a method to separate client and service code within an API. This separation allows different client and different provider implementations. Can be recognized from the name ending in Impl usually, just like in your stack trace java.net.PlainDatagramSocketImpl is the provider implementation where the DatagramSocket is the client side API.
You commented that you don't want to slow down the communication the entire way. There are several hacks to avoid it, for example measure the time in your code and slow the communication within the first 1-2 minutes starting at your first incoming method call. Then you can skip the sleep.
Another option would be to identify the misbehaving class in the library, JAD it and fix it. Then replace the original class file in the library.
I'm also currently seeing this problem as well with both Debian & RHEL. At this point I believe I've isolated it down to the NIC and/or the NIC driver. What hardware configuration do you have this also exhibits this problem? This seems to only occur on new Dell PowerEdge servers that we recently acquired that have Broadcom Corporation NetXtreme II BCM5708 Gigabit Ethernet NICs.
I too can confirm that it is the rapid generation of outbound UDP packets to many different IP addresses in a short window. I've attempted to write a simple Java application that can reproduce it (since ours is occurring with snmp4j).
EDIT
Look at my answer here: Java IOException: No buffer space available while sending UDP packets on Linux
I have got this error when i tried to run coherence cluster in two local JVM using the WIFI connection to database..
If i run it using the ethernet - it runs well.

Categories

Resources