Serial COMM port in windows remains owned after closing - java

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.

Related

jSerialComm: dynamically detect available serial ports (hotplug device)

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

Java RMI call slow first time

I'm working on a personal project for school where I have to user RMI to communicate between server and client.
Project info
The goal of my project is to retrieve stock info (from NYSE) for each day on the server at a specific time (after NYSE is closed). Each stock object is saved in a database. The information is retrieved over http and has nothing to do with RMI.
For the client it is also possible to fetch the stocks. When a user wants to fetch the stock object for the current day, it is directly fetched from the 3th party service. When a user, for example, wants to fetch Google's stock from last month, it is requested on the server over RMI. The server will the look for the stock object in the database and retrieve a Stock object and send it to the client.
Problem
When I start the client application, I have to login. The client will create a User object containing the username and password.
When I press the login button, it will take around 2 minutes before the main screen will be shown.
Below the source code where I setup the RMI connection.
Server (main.java)
public static void main(String[] args) throws UnknownHostException {
InetAddress IP= InetAddress.getLocalHost();
System.out.println("IP of my system is := "+IP.getHostAddress());
if(args.length == 1 && args[0].toLowerCase().equals("local")) {
System.out.println("Running on localhost");
System.setProperty("java.rmi.server.hostname", IP.getHostAddress());
} else {
System.out.println("rmi hostname is set to 37.97.223.70");
System.setProperty("java.rmi.server.hostname", "37.97.223.70");
}
try {
Registry reg = LocateRegistry.createRegistry(1099);
StockAppServer server = StockAppServer.getInstance();
reg.rebind("StockApp", server);
System.out.println("StockApp bound for StockAppServer object.");
} catch (RemoteException e) {
e.printStackTrace();
}
}
Based on the arguments that are passed to the application when it starts, I set the RMI hostname to my current IP address, or to the remote server address. The remote server address is a static IP, so this won't change.
Server (StockAppServer.java)
This class implements the interfaces that is used by the client to call methods on the server. So this class extends UnicastRemoteObject. When I start the server, registerStockTask() will be called. This method will fetch the ticker symbols (What are ticker symbols?) and then schedule a task to fetch all stock objects at a specific time.
private static StockAppServer _instance;
private List<User> loggedInUsers;
private List<Group> activeGroups;
private List<Notification> registeredNotifications;
private StockAppServer() throws IOException {
_instance = this;
this.loggedInUsers = new ArrayList<>();
this.activeGroups = new ArrayList<>();
this.registeredNotifications = new ArrayList<>();
this.registerStockTask();
clearActiveGroups();
checkForCompletedNotifications();
// Start the restful framework to allow incoming connections from the NodeJS server to manage new notification
Router.getInstance();
}
public static StockAppServer getInstance() {
try{
return _instance == null ? new StockAppServer() : _instance;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Client (main.java)
public static void main(String[] arguments) throws Exception {
args = arguments;
Application.launch();
}
#Override
public void start(Stage primaryStage) throws Exception {
InetAddress IP= InetAddress.getLocalHost();
System.out.println("IP of my system is := "+IP.getHostAddress());
if(args.length == 1 && args[0].toLowerCase().equals("local")) {
// Program started with local command, expect that server is running on local host
reg = LocateRegistry.getRegistry(IP.getHostAddress(), 1099);
System.out.println("Attempting to connect to RMI server over 127.0.0.1");
} else {
// Program started without additional commands. Except that "the server" is available;
reg = LocateRegistry.getRegistry("37.97.223.70", 1099);
System.out.println("Attempting to connect to RMI server over 37.97.223.70");
}
try {
StockApp.getInstance().setServerInterfaces((IStockSend) reg.lookup("StockApp"), (IUserHandling) reg.lookup("StockApp"));
} catch(RemoteException e) {
AlertMessage.showException("Unable to connect to server.", e);
} catch (NotBoundException e) {
AlertMessage.showException("No server has been found with the name \"StockApp\" on the remote host.\nPlease try again later", e);
}
LoginController.showMenu();
//FileNotFoundException e = new FileNotFoundException("Couldn't find file blabla.txt");
//AlertMessage.showException("Something went wrong. Please try again later.", e);
}
How I tried to solve my problem
When I test my applications local, there is no problem. The login method will be finished within a few milliseconds and I will be represented the main screen.
I started by turning of my firewall on my macbook. No result, login method still takes around 2 seconds.
I turned off the firewall om my Ubuntu server. No result, both firewalls on server and macbook are turned off. Login method still takes around 2 seconds.
On the server runs (thanks to jenkins) another (unrelated) program. This program uses sockets instead of RMI. When this program is not running, the login method still takes around 2 minutes.
In StockAppServer.java, I called the following method:
super(1099);
This has the same outcome as the above steps I took.
I don't know what else I can try to solve my problem.
I tried to give as much code as possible for the RMI part. I you need any other source code, just ask and I can update this question. Also, the source code is available via github: https://github.com/juleskreutzer/GSO-Maatwerk. Make sure to run the program with -remote param.
Update 1 (9-1-2017)
As yanys requested in the comments, I should run the following command:
dscacheutil -q host -a name localhost
this returns the following output:
Mac:
name: localhost
ip_address: 127.0.0.1
Ubuntu:
dscacheutil: command not found
Update 2 (9-1-2017)
I checked with the provider of my VPS where I run the java server on. On their side everything should be OK. According to them, it shouldn't be a dns problem. After some research, I found out that RMI uses both DNS and reverse DNS. It this case, reverse DNS was the issue. Please see my answer on how I solved my problem.
As EJP pointed out in the comments on the question, it was an DNS problem.
I contacted the support of my hosting provider to see if I had some wrong settings. They helped me a lot in solving this problem.
First we tested the speed of my VPS, this is around 1000mbit download and upload speed. After we checked this, they said there was nothing wrong on their side.
After doing some research, I found out that RMI uses both DNS and Reverse DNS. The problem was that I didn't setup the reverse DNS on my server. I already have a domain name to use for reverse DNS.
I than did the following:
Create a A-record on my website that points to the IP address of the server. I named it vps.mydomain.com
Add the reverse DNS in the control panel of my server
Change the hostname of my server to vps.mydomain.com*
*My server runs Ubuntu 16.04, on ubuntu machines with systemd, you can use the command
sudo hostnamectl set-hostname new-name
to change the hostname

Java DatagramChannel - Cannot ping port from external network

I am writing a server which uses a DatagramChannel (non-blocking) to send/receive data. It works flawlessly on my local network, but if I try to connect to it using the client application from a different network (i.e. over the internet), I cannot reach it.
Whilst running, if I use http://ping.eu/port-chk/ to check the port, it says it's closed. I have forwarded the appropriate ports and adjusted firewalls to appropriate levels.
My code is as follows:
public void runServer(int portNo)
{
try
{
serverChannel = DatagramChannel.open();
ipAddress = InetAddress.getLocalHost();
//ipAddress = InetAddress.getByName(getPublicIP());
//serverChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true); //Added in to try to fix
serverChannel.socket().bind(new InetSocketAddress(portNo));
serverChannel.configureBlocking(false);
serverChannel.socket().setReceiveBufferSize(receiveBufferSize);
serverChannel.socket().setSendBufferSize(sendBufferSize);
//serverChannel.connect(new InetSocketAddress(ipAddress,portNo)); //Added in to try to fix
serverRunning = true;
}
catch(IOException e)
{
e.printStackTrace();
}
}
The parts which are commented out have had no effect. The ipAddress variable in the example will fetch the local IP, where as the commented-out version will get the public IP of the computer.
If you could help me find out why I cannot connect to this port over the internet, I would be very grateful.
You haven't forwarded the ports correctly. Nothing to do with the code.
As #EJP has suggested, there doesn't seem to be anything wrong with my code. I have since hosted this server application using Amazon EC2, and it has worked flawlessly.
There is an issue with the firmware of my router which is preventing port forwarding.

How can I detect if a network card is not connected with Java without delay?

It there an API (NetworkInterface, InetAddress, etc) in Java with which I can detect that a network card is not connected.
The problem is that addressing some of the network API has a large timeout. But if the network card is not connected to any cable then we can skip it. The problem seems only to occur with Windows 7.
I had this same problem. I ended up using this:
Enumeration<NetworkInterface> eni = NetworkInterface.getNetworkInterfaces();
while(eni.hasMoreElements()) {
Enumeration<InetAddress> eia = eni.nextElement().getInetAddresses();
while(eia.hasMoreElements()) {
InetAddress ia = eia.nextElement();
if (!ia.isAnyLocalAddress() && !ia.isLoopbackAddress() && !ia.isSiteLocalAddress()) {
if (!ia.getHostName().equals(ia.getHostAddress()))
return true;
}
}
}
Works with Java 5+. Also indirectly checks DNS (by comparing names/addresses).
You could use some java system properties to set up the default time out for socket connection using
sun.net.client.defaultConnectTimeout
(all properties here)
But it seems to me that checking wether a specific Medium Access Controller is present or not is the job of the underlying OS. I can't tell you much about windows 7, I got a good OS since 12 years now (linux).
Regards,
Stéphane

Java Socket Returns True

I hope you can help. Im fairly new to progamming and Im playing around with java Sockets.
The problem is the code below. for some reason commSocket = new Socket(hostName, portNumber); is returning true even when it has not connected with the server (server not implemented yet!). Any ideas regarding this situation?
For hostName Im passing my local machine IP and for port a manually selected port.
public void networkConnect(String hostName, int portNumber){
try {
networkConnected = false;
netMessage = "Attempting Connection";
NetworkMessage networkMessage = new NetworkMessage(networkConnected, netMessage);
commSocket = new Socket(hostName, portNumber);
// this returns true!!
System.out.println(commSocket.isConnected());
networkConnected = true;
netMessage = "Connected: ";
System.out.println("hellooo");
} catch (UnknownHostException e){
System.out.println(e.getMessage());
} catch (IOException e){
System.out.println(e.getMessage());
}
}
Many thanks.
EDIT: new Socket(.., ..); is blocking isnt it? i thought in that case if that was processed without exceptions then we have a true connection?
EDIT: I played around with anti virus and now it is working!
Had that exact same situation a few days ago on a corporate computer, and searched for it for hours.
Check your antivirus, some antivirus (like E*** N**32) use live TCP scanning that make a connection succeed even if nothing is listening on the target port but will reset it later when you try to read/write from the socket.
Add this to your code:
commSocket.getOutputStream().write(0);
commSocket.getInputStream().read();
If you get a SocketException now, you should really consider to change your antivirus.
Alternatively, set a breakpoint in your application right after creating the socket, and then use netstat -ano (on Windows) to check which process id is associated with the other endpoint of your socket (which should be on your machine if you connect to localhost).
I would suggest you to disable your antivirus, but in some cases even that does not help to unload their broken live TCP scanning driver...
The Socket constructor connects right away and will throw an IOException if it doesn't succeed. So apparently you have connected successfully to a server (this could be one you didn't make yourself).

Categories