Should I close my socket after every successful message handle? - java

I am writing a program that has a Java Server/Client socket. There will be many messages sent back and forth, and in some situations, sending a message to the server and waiting for a period of time until the server has sent back a "execute" message.
Here is what I have planned:
1 Server (machine could possibly have antivirus security on it)
3 Clients (with room for more clients in future)
Parallel and Interleaved synchronization being carried out on the server side based up the clients output to the server.
When all machines are ready (in sync), when parallel all clients will be sent an "execute" message, when interleave clients will be sent an "execute" command in sequential order 1 by 1
I have started to build the program to have this setup above, and once a message is received on the server, the servers performs actions based upon the input and then sends back a message to the client. I have had problems in the past where messages were not sent or received properly, so my question is:
Do I keep the socket alive until then end of my program?
Or do I keep the socket open only until a successful transmission (a full handshake) has taken place and then close the socket? Leaving the client to connect again next time it wants to send a message.

You should certainly keep TCP connections open for as long as possible, but be prepared to create a new one on failure. You will need to use read timeouts at both ends to detect those.

Q: Should I open a new socket each connection, or keep it around and re-use it for subsequent connections?
A: "It depends".
I would encourage you to "Keep it Simple" and simply open new socket as needed ... until you find that you need otherwise.
By all means: keep the socket open for as long as you reasonably expect a "dialog" between your client and server. Don't force the client to establish a new connection if he's likely to want to talk again reasonably quickly.
Finally, take a look at these links regarding "Connection Pooling":
http://www.javacodegeeks.com/2013/08/simple-and-lightweight-pool-implementation.html
http://tutorials.jenkov.com/java-multithreaded-servers/thread-pooled-server.html

Whether or not you close the socket after a message depends on the protocol that you use between the server and the clients. Probably you define this yourself.
What is probably more important, is that you are able to serve multiple clients in parallel. Therefore, you need to start a separate thread for every client that requests a connection.
Personally, I made some applications with socket communication. To prevent keeping resources for too long when they are not used, but also not closing and reopening constantly when a connection is heavily used, I added a connection supervisor. This is yet another thread, that does is started when a connection is opened, and just performs a countdown from a predefined value (e.g. countdown from 60, decreqsing the value every second for a supervision time of 1 minute). When the counter reaches zero, order to close the socket, and terminate that particular thread.
When a socket is open, and receives a new message, then reset the supervision counter, so the socket will remain open, as long as the time between messages is less than 1 minute.

Related

How to wait on different events simultaneously

I have an open socket connection to a server.
On the one hand, in my code, I want to wait on a BlockingQueue for a message to be handed to me for sending to that server, then write it to the OutputStream.
When I send such a message, this normally expects an answer from the server (which needs to be read from the InputStream).
At the same time, I want to continuously listen on the socket's InputStream for spontaneous incoming messages from the server (server generated events).
Is there a recommended pattern for handling such a situation?
I obviously expect to have at least 2 threads involved (waiting on the two inputs - BlockingQueue and Socket). Any pointers are welcome on how to sync those, links to docs/blogs welcome.

how to understand java remote socket is unreachable when remote socket's device is shutdowned or application force closed

I have an as3 serversocket, we are connecting to the this serversocket via java socket(an android app). The problem is that, when serversocket application force closed, i couldnt find the a way to understand that remote socket is closed or unreachable, except when trying to flush() a message to that socket throws broken pipe error. The reason that i want to solve this problem in another way is not to make server application busy with connection check messages ?
A TCP connection is not a continuous flow like a river. It's a sequence of segments sent at discrete times - thus is more like cars on a road. So there is no way to be notified if the road is broken, until a car tries to reach the other end, fails, and calls you back.
You should simply keep sending cars at reasonable intervals (30 seconds?), thus instructing your server to do nothing when it receives a NOOP message (short for No Operation). The client will be programmed to start sending NOOP when the connection is idle (no message sent or received for 30 seconds), and when the driver calls back that he can't reach his destination, you close the current socket and attempt to create another one.
There are 3 ways for TCP to understand that connection has been closed:
One side got an error - it sends a Reset request to the other side to close the connection
One side actually wants to close the connection so it sends a FIN message to the other side
A time-out when trying to transmit something from one side to another. This time-out can only happen when a tcp-package is sent. After a connection has been made , tcp's packages are only sent on a data transmitting request (and connection closing request...).
So if one side disconnects suddenly, not in middle of data transmitting, there is no way of spotting a disconnection , but to send some package once a while.
You've found the only way. TCP doesn't provide any way of checking the state of a connection other than trying to use it. You can use this more intelligently, for example you can send yourself heartbeat messages and so forth. But there is no API that will tell you.
What you can do is let the server broadcast a I am alive message every 5/10 mins :)

How to "clear out" the receive buffer on a Java DatagramSocket?

I have a Java program that is constantly being sent UDP data from an external system.
Periodically, we need to stop receiving data (because another machine is handling it). During those times, my socket reader thread goes into a sleep loop. When it is time to start receiving packets, I go into socket.receive(Packet) again and have a buffer full of packets that I should not be handling. (The data came while in the "stop time".)
Is there a way to clear the buffer of a DatagramSocket?
If not, what is the best alternative? Set the buffer size to 0 when I go into the wait state and bring it back when I start to service packets again? Close the socket when I while I wait and open a new one when I come back?
Rather than having the downtime on the socket, have the downtime on whatever code processes the packets.
So the socket continues to receive like it normally would, but if it's on downtime, it just immediately drops the packet.
Not exactly the most efficient solution, but it's really easy to implement and might be useful as it leaves the node open in other cases for accepting different types of packets at different times.

implementing keepalives with Java

I am building a client-server application where I have to implement a keepalive mechanism in order to detect that the client has crashed or not. I have separate threads on both client and server side. the client thread sends a "ping" then sleeps for 3 seconds, while the server reads the BufferedInputStream and checks whether ping is received, if so it makes the ping counter equals zero, else it increments the counter by +1, the server thread then sleeps for 3 seconds, if the ping counter reaches 3, it declares the client as dead.
The problem is that when the server reads the input stream, its a blocking call, and it blocks until the next ping is received, irrespective of how delayed it is, so the server never detects a missed ping.
any suggestions, so that I can read the current value of the stream and it doesn't block if there is nothing on the incoming stream.
Thanks,
Java 1.4 introduced the idea of non-blocking I/O, represented by the java.nio package. This is probably what you need.
See this tutorial for how to use non-blocking I/O.
Also, assuming this isn't homework or a learning exercise, then I recommend using a more robust protocol framework such as Apache Mina or JBoss Netty, rather than building this stuff from scratch. See this comparison between them, and why you'd want to use them.
You can have a separate monitoring thread which monitors all the blocking connections. When a connection receives anything it can reset a counter. (I would treat any packet as good as a heartbeat) Your monitoring thread can increment this counter each times it runs and when it reaches a limit (i.e. because it wasn't reset back to zero) you can close the connection. You only need one such thread. The thread which is blocking on the connection you just closed with throw an IOException, waking the thread.
On the other side, a heartbeat can be triggered whenever a packet has not been sent for some period of time. This mean a busy connection doesn't send any heartbeats, it shouldn't need to.

Java socket not throwing exceptions on a dead socket?

We have a simple client server architecture between our mobile device and our server both written in Java. An extremely simple ServerSocket and Socket implementation. However one problem is that when the client terminates abruptly (without closing the socket properly) the server does not know that it is disconnected. Furthermore, the server can continue to write to this socket without getting any exceptions. Why?
According to documentation Java sockets should throw exceptions if you try to write to a socket that is not reachable on the other end!
The connection will eventually be timed out by Retransmit Timeout (RTO). However, the RTO is calculated using a complicated algorithm based on network latency (RTT), see this RFC,
http://www.ietf.org/rfc/rfc2988.txt
So on a mobile network, this can be minutes. Wait 10 minutes to see if you can get a timeout.
The solution to this kind of problem is to add a heart-beat in your own application protocol and tear down connection when you don't get ACK for the heartbeat.
The key word here (without closing the socket properly).
Sockets should always be acquired and disposed of in this way:
final Socket socket = ...; // connect code
try
{
use( socket ); // use socket
}
finally
{
socket.close( ); // dispose
}
Even with this precautions you should specify application timeouts, specific to your protocol.
My experience had shown, that unfortunately you cannot use any of the Socket timeout functionality reliably ( e.g. there is no timeout for write operations and even read operations may, sometimes, hang forever ).
That's why you need a watchdog thread that enforces your application timeouts and disposes of sockets that have been unresponsive for a while.
One convenient way of doing this is by initializing Socket and ServerSocket through corresponding channels in java.nio. The main advantage of such sockets is that they are Interruptible, that way you can simply interrupt the thread that does socket protocol and be sure that socket is properly disposed off.
Notice that you should enforce application timeouts on both sides, as it is only a matter of time and bad luck when you may experience unresponsive sockets.
TCP/IP communications can be very strange. TCP will retry for quite a while at the bottom layers of the stack without ever letting the upper layers know that anything happened.
I would fully expect that after some time period (30 seconds to a few minutes) you should see an error, but I haven't tested this I'm just going off how TCP apps tend to work.
You might be able to tighten the TCP specs (retry, timeout, etc) but again, haven't messed with it much.
Also, it may be that I'm totally wrong and the implementation of Java you are using is just flaky.
To answer the first part of the question (about not knowing that the client has disconnected abruptly), in TCP, you can't know whether a connection has ended until you try to use it.
The notion of guaranteed delivery in TCP is quite subtle: delivery isn't actually guaranteed to the application at the other end (it depends on what guaranteed means really). Section 2.6 of RFC 793 (TCP) gives more details on this topic. This thread on the Restlet-discuss list and this thread on the Linux kernel list might also be of interest.
For the second part (not detecting when you write to this socket), this is probably a question of buffer and timeout (as others have already suggested).
I am facing the same problem.
I think when you register the socket with a selector it doesn't throw any exception.
Are you using a selector with your socket?

Categories