How does the PCFMessageAgent handle disconnecting? - java

I'm trying to get an understanding of how the PCFMessageAgent manages connections to ensure I'm cleaning up everything properly.
For example, at what point is the connection disconnected once I've created the object and I'm done with it?
PCFMessageAgent agent = new PCFMessageAgent ("localhost", 1414, "CLIENT");
The example in the documentation does not show any disconnect call, but I want to be sure I'm not assuming anything.
If it matters, I'm currently on MQ version 7.5, but it doesn't appear this has changed much.

Always cleanup your stuff.
If you connect it, then make sure you disconnect from it
If you open it, then make sure you close it
i.e.
if (agent != null)
agent.disconnect();

Related

How to use dbus and NetworkManager to activate a connection

as per my previous SO questions, I'm still working on controlling NetworkManager via dbus from a Java application. I want to activate an existing wireless connection so here's my code, stripped as much as possible of irrelevancies:
DBusInterface iface = ...;
var nmIface = (NetworkManagerIface) instance.getRemoteObject(NetworkManagerIface._NM_IFACE, NetworkManagerIface._NM_PATH, NetworkManagerIface.class);
System.out.println("Attempting connection to " + iface.getObjectPath());
var result = nmIface.ActivateConnection(new DBusPath(iface.getObjectPath()), new DBusPath("/"), new DBusPath("/"));
System.out.println("Activate Connection " + result.getPath());
where NetworkManagerIface is here.
This runs alright and prints:
Attempting connection to /org/freedesktop/NetworkManager/Settings/4
Activate Connection /org/freedesktop/NetworkManager/ActiveConnection/4
so it looks like the call to ActivateConnection worked, inasmuch as it returned something sensible. However, the command nmcli c show shows the connection as not in-use.
NetworkManager holds eight connections in our system:
# dbus-send --system --print-reply --dest=org.freedesktop.NetworkManager /org/freedesktop/NetworkManager/Settings org.freedesktop.DBus.Properties.Get string:org.freedesktop.NetworkManager.Settings string:Connections
method return time=1575940954.061910 sender=:1.8 -> destination=:1.70 serial=9361 reply_serial=2
variant array [
object path "/org/freedesktop/NetworkManager/Settings/2"
object path "/org/freedesktop/NetworkManager/Settings/7"
object path "/org/freedesktop/NetworkManager/Settings/3"
object path "/org/freedesktop/NetworkManager/Settings/5"
object path "/org/freedesktop/NetworkManager/Settings/4"
object path "/org/freedesktop/NetworkManager/Settings/8"
object path "/org/freedesktop/NetworkManager/Settings/1"
object path "/org/freedesktop/NetworkManager/Settings/6"
]
The existing connection is the wired (ethernet) connection and I want to add a wireless connection. Why doesn't my ActivateConnection call do this?
If the ActivateConnection call returns success, but afterwards the profile is not actually activating/activated, it stands to reason that the activation shortly after failed.
Look at NetworkManager's logfile to understand why the activation failed. Possibly enable level=TRACE logging, see https://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/contrib/fedora/rpm/NetworkManager.conf#n28 for hints about logging.
You could also run nmcli monitor in another terminal, to get an idea what happens.
The existing connection is the wired (ethernet) connection and I want to add a wireless connection
You want to add a connection profile? That is not what ActivateConnection does. See AddConnection and the D-Bus API in general: https://developer.gnome.org/NetworkManager/stable/spec.html
Why doesn't my ActivateConnection call do this?
Sorry, I don't understand. Do what?

Java Mail api, connection gets lost during message process

In our java mail (using Java Mail API) application we first connect to the mail server, fetch messages, process headers and then afterwards process the message bodies and attachments using pop3 as usual.
Session session = Session.getInstance(props, null);
Store store = session.getStore(urln);
store.connect();
Folder f = store.getFolder("INBOX");
f.open(READ);
Messages m = f.getMessages(..);
for (Message m : messages) {
if (!store.isConnected()) {
//raise exception
}
processSubject();
processFrom();
processBodyAndAttachments();
..
}
The implementation works fine on most environments, but on some customer the storeconnection gets lost during the process in the for loop. We can see the raises exception in the logs. My questions:
AFAIK, the mail server can sometimes reject new connections, but does
it terminate current living connections (may be becasue of too much
connections or disconnects old ones to give access to the new ones?)
When the store is disconnected, does the folder gets closed too?
Is it better to check the folder?
The connection may be lost everywhere in the for loop and it does not
seem to be a good practise to put isConnected check everywhere in the
loop, it will make the code dirty and also cause performance issues,
is it a good practise to put in a try catch block and check for
IOExceptions? (Folder closed) Or other suggestions? Which exceptions
should be handled? There may be some cases where the message is not
parseable but connection is healthy.
What about adding a disconnect listener?
Network connections can be broken for a variety of reasons. Your program always has to be prepared for the connection to drop at any time.
With POP3, there is only one connection, so if the connection is dropped the store should be disconnected and the folder should be closed.
If the Folder is open, check the Folder. Otherwise check the Store.
You need a strategy for handling failures. If you keep track of what messages have been successfully processed you may be able to restart the processing at the next message after a failure. A lot of the details depend on your environment and your application requirements.
A disconnect listener won't make this easier.

How do i find if (java) socket is still valid? [duplicate]

This question already has answers here:
Java socket API: How to tell if a connection has been closed?
(9 answers)
Closed 5 years ago.
When I'm using e.g. PuTTY and my connection gets lost (or when I do a manual ipconfig /release on Windows), it responds directly and notifies my connection was lost.
I want to create a Java program which monitors my Internet connection (to some reliable server), to log the date/times when my internet fails.
I tried use the Socket.isConnected() method but that will just forever return "true". How can I do this in Java?
Well, the best way to tell if your connection is interrupted is to try to read/write from the socket. If the operation fails, then you have lost your connection sometime.
So, all you need to do is to try reading at some interval, and if the read fails try reconnecting.
The important events for you will be when a read fails - you lost connection, and when a new socket is connected - you regained connection.
That way you can keep track of up time and down time.
Even though TCP/IP is "connection oriented" protocol, normally no data is sent over an idle connection. You can have a socket open for a year without a single bit sent over it by the IP stack. In order to notice that a connection is lost, you have to send some data on the application level.(*) You can try this out by unplugging the phone cable from your ADSL modem. All connections in your PC should stay up, unless the applications have some kind of application level keepalive mechanism.
So the only way to notice lost connection is to open TCP connection to some server and read some data from it. Maybe the most simple way could be to connect to some FTP server and fetch a small file - or directory listing - once in a while. I have never seen a generic server which was really meant to be used for this case, and owners of the FTP server may not like clients doing this.
(*) There is also a mechanism called TCP keepalive but in many OS's you have to activate it for all applications, and it is not really practical to use if you want to notice loss of connection quickly
If the client disconnects properly, a read() will return -1, readLine() returns null, readXXX() for any other X throws EOFException. The only reliable way to detect a lost TCP connection is to write to it. Eventually this will throw an IOException 'connection reset', but it takes at least two writes due to buffering.
Why not use the isReachable() method of the java.net.InetAddress class?
How this works is JVM implementation specific but:
A typical implementation will use ICMP ECHO REQUESTs if the privilege can be obtained, otherwise it will try to establish a TCP connection on port 7 (Echo) of the destination host.
If you want to keep a connection open continually so you can see when that fails you could connect to server running the ECHO protocol yourself rather than having isReachable() do it for you and read and write data and wait for it to fail.
You might want to try looking at the socket timeout interval. With a short timeout (I believe the default is 'infinite timeout') then you might be able to trap an exception or something when the host becomes unreachable.
Okay so I finally got it working with
try
{
Socket s = new Socket("stackoverflow.com",80);
DataOutputStream os = new DataOutputStream(s.getOutputStream());
DataInputStream is = new DataInputStream(s.getInputStream());
while (true)
{
os.writeBytes("GET /index.html HTTP/1.0\n\n");
is.available();
Thread.sleep(1000);
}
}
catch (IOException e)
{
System.out.println("connection probably lost");
e.printStackTrace();
}
Not as clean as I hoped but it's not working if I leave out the os.writeBytes().
You could ping a machine every number of seconds, and this would be pretty accurate. Be careful that you don't DOS it.
Another alternative would be run a small server on a remote machine and keep a connection to it.
Its probably simpler to connect to yahoo/google or somewhere like this.
URL yahoo = new URL("http://www.yahoo.com/");
URLConnection yc = yahoo.openConnection();
int dataLen = yc.getContentLength() ;
Neil
The isConnected()method inside Socket.java class is a little misleading. It does not tell you if the socket is currently connected to a remote host (like if it is unclosed). Instead, it tells you whether the socket has ever been connected to a remote host. If the socket was able to connect to the remote host at all, this method returns true, even after that socket has been closed. To tell if a socket is currently open, you need to check that isConnected() returns true and isClosed() returns false.
For example:
boolean connected = socket.isConnected() && !socket.isClosed();

How to make a stable tcp-socket connection without a server response?

I need some help with the following problem:
I open a tcp-socket in the constructor then proceed to provide a object over an object output-stream to the server. I have no control over the server and don't get any response back.
How can I detect that the connection was lost? Will I always get the IOExeption-Error when trying to write? Because according to javadoc once a connection was successfully made most of the checks are basically useless to me.
Additionally what is the best way to reconnect a socket? Set the reference to "Null" then create a new one?
Here is my current approach:
I have a status-list in which I have the following statuses:
SocketSuccess; SocketFailure; MessageSuccess; MessageFailure;
My idea is kind of like a state-machine so check first what the last status was. If the connection was successfull or the last message was successfull then try to send the message. When I get a IOExeption then set the status MessageFailure, save the Message locally till I get a successfull connection again.
Or are there any recommended patterns for this kind of situation?
Clearing all your douts. If the connection with the server is lost then the client will throw IOException and that will kill the application but if you have handled the exception and tried to reconnect with the server and Re-establish the input output stream the your message function will start again. The predefined messages you are using will travel only when there is a connection between server and client. So when the connection is lost you will get IOException and when you handle that exception and try to reconnect a new input output stream should be established that will carry your messaging service.

Java detect lost connection [duplicate]

This question already has answers here:
Java socket API: How to tell if a connection has been closed?
(9 answers)
Closed 5 years ago.
When I'm using e.g. PuTTY and my connection gets lost (or when I do a manual ipconfig /release on Windows), it responds directly and notifies my connection was lost.
I want to create a Java program which monitors my Internet connection (to some reliable server), to log the date/times when my internet fails.
I tried use the Socket.isConnected() method but that will just forever return "true". How can I do this in Java?
Well, the best way to tell if your connection is interrupted is to try to read/write from the socket. If the operation fails, then you have lost your connection sometime.
So, all you need to do is to try reading at some interval, and if the read fails try reconnecting.
The important events for you will be when a read fails - you lost connection, and when a new socket is connected - you regained connection.
That way you can keep track of up time and down time.
Even though TCP/IP is "connection oriented" protocol, normally no data is sent over an idle connection. You can have a socket open for a year without a single bit sent over it by the IP stack. In order to notice that a connection is lost, you have to send some data on the application level.(*) You can try this out by unplugging the phone cable from your ADSL modem. All connections in your PC should stay up, unless the applications have some kind of application level keepalive mechanism.
So the only way to notice lost connection is to open TCP connection to some server and read some data from it. Maybe the most simple way could be to connect to some FTP server and fetch a small file - or directory listing - once in a while. I have never seen a generic server which was really meant to be used for this case, and owners of the FTP server may not like clients doing this.
(*) There is also a mechanism called TCP keepalive but in many OS's you have to activate it for all applications, and it is not really practical to use if you want to notice loss of connection quickly
If the client disconnects properly, a read() will return -1, readLine() returns null, readXXX() for any other X throws EOFException. The only reliable way to detect a lost TCP connection is to write to it. Eventually this will throw an IOException 'connection reset', but it takes at least two writes due to buffering.
Why not use the isReachable() method of the java.net.InetAddress class?
How this works is JVM implementation specific but:
A typical implementation will use ICMP ECHO REQUESTs if the privilege can be obtained, otherwise it will try to establish a TCP connection on port 7 (Echo) of the destination host.
If you want to keep a connection open continually so you can see when that fails you could connect to server running the ECHO protocol yourself rather than having isReachable() do it for you and read and write data and wait for it to fail.
You might want to try looking at the socket timeout interval. With a short timeout (I believe the default is 'infinite timeout') then you might be able to trap an exception or something when the host becomes unreachable.
Okay so I finally got it working with
try
{
Socket s = new Socket("stackoverflow.com",80);
DataOutputStream os = new DataOutputStream(s.getOutputStream());
DataInputStream is = new DataInputStream(s.getInputStream());
while (true)
{
os.writeBytes("GET /index.html HTTP/1.0\n\n");
is.available();
Thread.sleep(1000);
}
}
catch (IOException e)
{
System.out.println("connection probably lost");
e.printStackTrace();
}
Not as clean as I hoped but it's not working if I leave out the os.writeBytes().
You could ping a machine every number of seconds, and this would be pretty accurate. Be careful that you don't DOS it.
Another alternative would be run a small server on a remote machine and keep a connection to it.
Its probably simpler to connect to yahoo/google or somewhere like this.
URL yahoo = new URL("http://www.yahoo.com/");
URLConnection yc = yahoo.openConnection();
int dataLen = yc.getContentLength() ;
Neil
The isConnected()method inside Socket.java class is a little misleading. It does not tell you if the socket is currently connected to a remote host (like if it is unclosed). Instead, it tells you whether the socket has ever been connected to a remote host. If the socket was able to connect to the remote host at all, this method returns true, even after that socket has been closed. To tell if a socket is currently open, you need to check that isConnected() returns true and isClosed() returns false.
For example:
boolean connected = socket.isConnected() && !socket.isClosed();

Categories