jSerialComm: dynamically detect available serial ports (hotplug device) - java

I've created a Java GUI which lists all serial ports in a drop down menu from which the user selects the correct port and clicks connect. Connection to an Arduino is then established and the user is able to perform some actions. I get the available ports using Fazecast JSerialComm:
SerialPort[] ports = SerialPort.getCommPorts();
I grab the ports and put the results into the drop down. This works flawlessly BUT only when the Arduino is plugged into the Mac BEFORE launching my Java GUI. Is there a way to detect a hotplugged device in Java? I already thought of getting the com ports periodically (every second or so) but to me that does seem to be a very elegant solution.

update:
I found this answered by another user:
Serial communication manager have APIs to find serial port names like COMxx dynamically. Just connect your USB-USRT IC and SCM library will tell you the device node for it. Just google for Serial communication manager. It is hosted on GitHub.
src
You might do this by checking if the port is opened or not after trying to open it using:
SerialPort[] serialPorts = SerialPort.getCommPorts();
SerialPort liveSerialPort = null;
for (SerialPort p: serialPorts) {
p.openPort();
if (p.isOpen()) {
liveSerialPort = p;
System.out.println("HERE opened port = " + liveSerialPort.getSystemPortName());
break;
}
}

Related

Cannot Get DNS Requests via Java Code in Windows 10 and DLINK DIR-615 router

So I am working on a software that will monitor(and may alter by acting as a Forrowder) all the DNS requests made by my router.
What I did?
So for first I wrote a Java code that can listens to a specific port and prints all the requests to the console[For now I just want to test with the requests].
The code is:
import java.net.*;
import java.io.*;
public class PortLogger{
public static void main(String[] args) {
LoggerServer loggerServer = new LoggerServer(53);
loggerServer.start();
}
}
class LoggerServer extends Thread{
private int port;
public LoggerServer(int port){
this.port = port;
}
#Override
public void run(){
try{
int id = 1;
ServerSocket server = new ServerSocket(port);
System.out.println("Server Listening at port " + port);
Socket client;
while(true){
client = server.accept();
ClientHandler clientHandler = new ClientHandler(client, id++);
clientHandler.start();
}
}catch(Exception ex){
System.out.println("Exception at Server : 1 :: EX = " + ex);
}
}
}
class ClientHandler extends Thread{
private Socket client;
private int id;
public ClientHandler(Socket client, int id){
this.client = client;
this.id = id;
}
#Override
public void run(){
try {
String data = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
while(true){
data = reader.readLine();
if(data.length() > 0){
System.out.println("Client : " + id + " :: " + data);
}
}
}catch(Exception ex){
System.out.println("Exception at Client : " + id + " :: EX = " + ex);
}
}
}
The sole propose of this code for now is to Show me all the requests made to the server.
I know that I also have to change the DNS Server in my router for this.
So, for that I first tried by going to internet setup and put the local IP of my computer as DNS server.
But it was showing :
DNS IP and LAN IP must be on different networks!
But I found another way to do it.
It is as follows:
I went to the setup wizard of the router and the set the DNS Server to the same IP.
Surprisingly this worked!
[I have no idea whether this is a bug in the D-Link Firmware or not.
I have also added an exception to allow all request both inbound and outbound to port 53.
What is the problem?
So now the problem is that even after successfully changing the DNS to my servers. There seemed to be no requests at all to the console. I tried a lot but nothing.
I checked that the program was working fine by voluntarily sending request to it using telnet?
Now am I doing anything wrong or there is some bug with the router(its is a old one).
NOTE: The black lines on the images are just to hide my public IP address nothing special.
EDIT: I tried a few more times then found that websites were not opening when I changed the DNS in my router but still nothing in the console!
While it is difficult to give you a complete answer why your application doesn't work I can suggest some ways to investigate:
Port 53 is a privileged port. This means on Linux binding to that port requires root privileges and the application will throw an exception due to 'permission denied' if executed as a 'normal' user. As you are using Windows I don't know what it does if you try to bind as a 'normal' user, or you might be executing as an Admin user (or whatever the equivalent of 'root' is in Windows) and you don't know it. It might even just silently fail i.e. appear to bind when in fact it hasn't and no data is passed through you your application. As an aside, defaulting to 'root' as the default execution user in Linux is not the norm because it's insecure and most Linux distributions if not all do not allow this by default i.e. you can have this but you have to tell the distribution this is what you intend during installation. I'll let you come to your own conclusions what stance Windows takes for making users 'admin'...
In a scenario such as this if it were me I would immediately go to some networking tools to see what is happening. On Linux this is tcpdump or Wireshark. You can also get Wireshark for Windows as it's a GUI application. This will let you monitor and filter network traffic and so will be independent of your application. You can filter by source or destination address and/or port number.
I would leave the DNS setting alone in the router and change the DNS settings in one machine first, call it the test client, and set its DNS address to the machine where your application is running. Using tcpdump or Wireshark you can then make requests on your test_client e.g. browser requests and see the resulting network traffic.
You never mentioned if after changing your router's DNS settings all browser requests from clients fail. This is what I would expect to see if your router can no longer get a name resolution. However there maybe some DNS caching going on in your clients so you may appear to get successful DNS requests on your test_client. Again look at network traffic or use a Linux client which will provide you with much better networking tools.

Creating a DHCP client list java

I'm trying to write a program that will show a DHCP client list in Java. I want to get the IP addresses, MAC addresses and the host names of all the devices connected to my wifi network.
I have a Belkin router. Its homepage has a 'DHCP client list' option which when clicked shows me this table :
That's exactly what I'm looking for. But I want to show all this data in the form of a list in a Java Swing program. I also want to be able to update this list by pressing a refresh button. Is there any way to achieve this?
It should look something like this :
I've written a basic java program that shows all the IP addresses that are online. Here's the code :
public static void main(String[] args) throws IOException {
InetAddress localhost = InetAddress.getLocalHost();
// this code assumes IPv4 is used
byte[] ip = localhost.getAddress();
for (int i = 1; i <= 254; i++)
{
ip[3] = (byte)i;
InetAddress address = InetAddress.getByAddress(ip);
if (address.isReachable(1000))
{
// machine is turned on and can be pinged
System.out.println(address + "is online");
}
else if (!address.getHostAddress().equals(address.getHostName()))
{
// machine is known in a DNS lookup
System.out.println(address + "is in a DNS lookup");
}
else
{
// the host address and host name are equal, meaning the host name could not be resolved
System.out.println(address + " is not online");
}
}
}
But this doesn't serve the purpose and it's really slow. I want to write a Swing program that'll show me the DHCP client list as seen in the image above.
Any help is appreciated.
I would think about three possible alternatives:
1-The one you implemented that is slow but it can work. You need to find a JAVA API to get the MAC addresses of received messages (I don't know if it exists or not). You can also send ARP messages asking "who has this IP address) and obtain the MAC address from the response. Use some Java interface for pcap library: jNetPcap vs Jpcap , http://jnetpcap.com/
2-Create an app that accesses your router web interface using HTTP and sending the appropriate messages with data as if you were using the UI. In this way you can programatically follow the steps a human would go and get the list that you browser shows, parse it and obtain the data.
3-If the router/access point provides a web API, which I doubt, you can use it.

Java server-client game

Ok, I am quite new to network programming and I am trying to solve this problem:
I have GUI based Java SE game for max 7 players and I want it to support multiplayer over the Internet.
Every instance of game would have its own client sending and receiving string.
And here comes the problem I cannot sufficiently solve. I need server and its only functionality is keeping client's sockets opened and on receiving some string just forward it to other clients. My first idea was to run server on the first player's machine and other players can connect to that server via its IP from outside. Now I discovered that getting public interface IP is not that easy as I thought so I searched and found the code written below to get some IP's that SHOULD be available from outside. When I try this at localhost, resulted IP is always some IPv6 + port and connecting from client using this credentials is successful and it works. When I start the server on another machine and copy these credentials for connecting from another computer it fails (it either doesn't connect or if it does and client sends message, server doesn't receive any).
So my next idea was to use some public IP on remote hosting server. So there would be some server running 24/7 (or if I programmatically from game tell him so) and I use its IP to unite all clients. I just don't know how to make this thing working and what technologies use.
I hope I explained my problem clearly and thanks for any ideas or even solutions :)
Get machine's public interface IP (where server is running) and prints that out code:
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface iface = interfaces.nextElement();
if (iface.isLoopback() || !iface.isUp()) { //127.xxx loopback
continue;
}
Enumeration<InetAddress> addresses = iface.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
String tmp = addr.getHostAddress();
if (tmp.startsWith("192.168.") //local IP
|| tmp.startsWith("10.") //local IP
|| tmp.startsWith("172.16.") //local IP
|| tmp.startsWith("172.31.") //local IP
|| tmp.startsWith("169.254") //single network IP
|| tmp.equals("255.255.255.255")) { //broadcast address
continue;
}
//cut "%net9","%wlan" etc stuff off
IP = tmp.substring(0, Math.max(0, tmp.indexOf('%')));
port=server.getPort();
System.out.println(IP + " " + port);
}
}
if running on a "local network" then having a serversocket is fine, but we deal with NAT and the internet which means that 98% of machines are not directly internet visible. (i.e. opening a TCP port for listening on the machine will not result in the machines Internet IP address having that port be listened to. )
The initial option would be to have a server on public hosting which mediates communication between players and each players machine is responsible for maintaining 'game state' but then you run into the issue of synchronization. (e.g. one players machine thinks that they have hit and killed another player prior to that machine receiving a command to tell it that the opponent has moved. )
The current method of thinking for this paticular problem is to have the server maintain the 'game state' (e.g. player positions, health, weapon damage, etc. )
having players send 'commands' to the server (e.g. move, fire, jump. ) and then having the server report to all players the 'minor' game state changes. (so Time becomes an important factor and all messages between clients and server need to be timestamped. )
so your clients maintain what they believe 'game state' to be, recieving updates from the server to 'correct' errors.
In addition to this every once in a while the server should send a dump of the entire 'game state' to each player as a 'sync' message to ensure what they believe to be the game state 'is' the actual game state.
If your language of choice was "C" it would be trivial to take the md5 checksum of the entire game state structure and then transmit this to players periodically and only performing a sync message..
The links below should give you a good starting point.
A good start
And the enclosing page with a little bit more detail

how to know what are the input devices connected to the system

iam just simply trying to know what are the input devices and output devices connected to the system. Do there any api to get information about input/output devices using java?
EDIT
independent of any operating system.
Please suggest.
To find what usb devices are connected to the system you can use jUSB. This article has more in-depth information on how to use the api. In particular, to find all usb devices (slightly modified from the article):
Host host = HostFactory.getHost();
// Obtain a list of the USB buses available on the Host.
Bus[] bus = host.getBusses();
// Traverse through all the USB buses.
for (int i = 0; i < bus.length; i++) {
// Access the root hub on the USB bus and obtain the number of USB ports available on the root hub.
Device root = bus[i].getRootHub();
int totalPorts = root.getNumPorts();
// Traverse through all the USB ports available on the
// root hub. It should be mentioned that the numbering
// starts from 1, not 0.
for (int j=1; j<=total_port; j++) {
// Obtain the Device connected to the port.
Device device = root.getChild(j);
if (device != null) {
// USB device available, do something here.
}
}
}
Similarly, you can use the api for MIDI systems to find what MIDI devices are connected, see the java tutorials for more information.
I think you should try commandline via java Runtime.getRuntime().exec(command);
According to this site http://michaelminn.com/linux/command_line
Following command should return this:
lspci: Lists information about devices connected to the internal PCI busses.
lspci -vv: Full dump of information.
so
String command="lspci";
And from windows you may need to download DevCon command! http://support.microsoft.com/kb/311272/EN-US
so
String command="devcon find";

Serial COMM port in windows remains owned after closing

I have a problem with comm ports in JAVA.
I'm using Java version, 1.5 because that version still have access to windows COMM ports (serials).
The problem is that the command throws the exception:
javax.comm.PortInUseException: Port currently owned by Unknown Windows Application
The thing is that the application opens the comm port for the first time, then I close the comm when the user exits some window.
But the user may return to that window, and therefore I try to open again the same port:
I close with:
if (puertoSerie != null) {
puertoSerie.removeEventListener();
puertoSerie.close();
puertoSerie = null;
}
So I added a PortOwnershipListener:
idPuerto.addPortOwnershipListener(new MyResolver());
And the error says:
Somebody else has the port
Somebody else has the port
That occurs when :
case PORT_OWNERSHIP_REQUESTED:
if (owned) {
System.out.println("Owned ... Somebody else has the port");
} else {
System.out.println("Somebody else has the port");
}
Any Idea how to work around this?
Best Regards
The new java JDK 1.7 also has serial port programming using the java.comm and rxtx api's.
You can install them and run them if you like and you can use serialPort.close(); to end the connection.

Categories