I'm trying to learn Socket and I'm confused by following text from Oracle's website:
setSoTimeout
public void setSoTimeout(int timeout) throws SocketException
Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.
My questions:
What is SO_TIMEOUT?
Socket is the endpoint of a connection. If I say
mySocket.setSoTimeout(2000);
Does it mean that I'm blocking reading any input from the Server/Client for this socket for 2000 millisecond and after this time the socket is ready to read data?
What does it mean timeout expire?
What is the option which must be enabled prior to blocking operation?
Infinite Timeout means that the socket doesn't read anymore?
Does it mean that I'm blocking reading any input from the Server/Client for this socket for 2000 millisecond and after this time the socket is ready to read data?
No, it means that if no data arrives within 2000ms a SocketTimeoutException will be thrown.
What does it mean timeout expire?
It means the 2000ms (in your case) elapses without any data arriving.
What is the option which must be enabled prior to blocking operation?
There isn't one that 'must be' enabled. If you mean 'may be enabled', this is one of them.
Infinite Timeout means that the socket doesn't read anymore?
What a strange suggestion. It means that if no data ever arrives you will block in the read forever.
The JavaDoc explains it very well:
With this option set to a non-zero timeout, a read() call on the
InputStream associated with this Socket will block for only this
amount of time. If the timeout expires, a
java.net.SocketTimeoutException is raised, though the Socket is still
valid. The option must be enabled prior to entering the blocking
operation to have effect. The timeout must be > 0. A timeout of zero
is interpreted as an infinite timeout.
SO_TIMEOUT is the timeout that a read() call will block. If the timeout is reached, a java.net.SocketTimeoutException will be thrown. If you want to block forever put this option to zero (the default value), then the read() call will block until at least 1 byte could be read.
This example made everything clear for me:
As you can see setSoTimeout prevent the program to hang! It wait for SO_TIMEOUT time! if it does not get any signal it throw exception! It means that time expired!
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class SocketTest extends Thread {
private ServerSocket serverSocket;
public SocketTest() throws IOException {
serverSocket = new ServerSocket(8008);
serverSocket.setSoTimeout(10000);
}
public void run() {
while (true) {
try {
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
Socket client = serverSocket.accept();
System.out.println("Just connected to " + client.getRemoteSocketAddress());
client.close();
} catch (SocketTimeoutException s) {
System.out.println("Socket timed out!");
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
public static void main(String[] args) {
try {
Thread t = new SocketTest();
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Related
I've created a client-server connection, something like a chat system. Previously I was using a while loop on the client side, and it was waiting to read a message from the console every time (of course server has a while loop as well to serve forever). But now, I'm trying to first create a connection at the beginning of the session, and then occasionally send a message during the session, so to maintain a permanent and persistent connection.
Currently, without the while loop, the client closes the connection and I don't know how to find a workaround.
Here is the client code:
import java.net.*;
import java.io.*;
public class ControlClientTest {
private Socket socket = null;
// private BufferedReader console = null;
private DataOutputStream streamOut = null;
public static void main(String args[]) throws InterruptedException {
ControlClientTest client = null;
String IP="127.0.0.1";
client = new ControlClientTest(IP, 5555);
}
public ControlClientTest(String serverName, int serverPort) throws InterruptedException {
System.out.println("Establishing connection. Please wait ...");
try {
socket = new Socket(serverName, serverPort);
System.out.println("Connected: " + socket);
start();
} catch (UnknownHostException uhe) {
System.out.println("Host unknown: " + uhe.getMessage());
} catch (IOException ioe) {
System.out.println("Unexpected exception: " + ioe.getMessage());
}
String line = "";
// while (!line.equals(".bye")) {
try {
Thread.sleep(1000);
//TODO get data from input
// line = console.readLine();
line="1";
if(line.equals("1"))
line="1,123";
streamOut.writeUTF(line);
streamOut.flush();
} catch (IOException ioe) {
System.out.println("Sending error: " + ioe.getMessage());
}
// }
}
public void start() throws IOException {
// console = new BufferedReader(new InputStreamReader(System.in));
streamOut = new DataOutputStream(socket.getOutputStream());
}
}
And here is the Server code:
import java.awt.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ControlServer {
private Socket socket = null;
private ServerSocket server = null;
private DataInputStream streamIn = null;
public static void main(String args[]) {
ControlServer server = null;
server = new ControlServer(5555);
}
public ControlServer(int port) {
try {
System.out
.println("Binding to port " + port + ", please wait ...");
server = new ServerSocket(port);
System.out.println("Server started: " + server);
System.out.println("Waiting for a client ...");
socket = server.accept();
System.out.println("Client accepted: " + socket);
open();
boolean done = false;
while (!done) {
try {
String line = streamIn.readUTF();
// TODO get the data and do something
System.out.println(line);
done = line.equals(".bye");
} catch (IOException ioe) {
done = true;
}
}
close();
} catch (IOException ioe) {
System.out.println(ioe);
}
}
public void open() throws IOException {
streamIn = new DataInputStream(new BufferedInputStream(
socket.getInputStream()));
}
public void close() throws IOException {
if (socket != null)
socket.close();
if (streamIn != null)
streamIn.close();
}
}
I would like to summarize some good practices regarding the stability of TCP/IP connections which I apply on a daily basis.
Good practice 1 : Built-in Keep-Alive
socket.setKeepAlive(true);
It automatically sends a signal after a period of inactivity and checks for a reply. The keep-alive interval is operating system dependent though, and has some shortcomings. But all by all, it could improve the stability of your connection.
Good practice 2 : SoTimeout
Whenver you perform a read (or readUTF in your case), your thread will actually block forever. In my experience this is bad practice for the following reasons: It's difficult to close your application. Just calling socket.close() is dirty.
A clean solution, is a simple read time-out (e.g. 200ms). You can do this with the setSoTimeoutmethod. When the read() method timeouts it will throw a SocketTimeoutException. (which is a subclass of IOException).
socket.setSoTimeout(timeoutInterval);
Here is an example to implement the loop. Please note the shutdown condition. Just set it to true, and your thread will die peacefully.
while (!shutdown)
{
try
{
// some method that calls your read and parses the message.
code = readData();
if (code == null) continue;
}
catch (SocketTimeoutException ste)
{
// A SocketTimeoutExc. is a simple read timeout, just ignore it.
// other IOExceptions will not be stopped here.
}
}
Good practice 3 : Tcp No-Delay
Use the following setting when you are often interfacing small commands that need to be handled quickly.
try
{
socket.setTcpNoDelay(true);
}
catch (SocketException e)
{
}
Good practice 4 : A heartbeat
Actually there are a lot of side scenario's that are not covered yet.
One of them for example are server applications that are designed to only communicate with 1 client at a time. Sometimes they accept connections and even accept messages, but never reply to them.
Another one: sometimes when you lose your connection it actually can take a long time before your OS notices this. Possibly due to the shortcomings described in good practice 3, but also in more complex network situations (e.g. using RS232-To-Ethernet converters, VMware servers, etc) this happens often.
The solution here is to create a thread that sends a message every x seconds and then waits for a reply. (e.g. every 15 seconds). For this you need to create a second thread that just sends a message every 15 seconds. Secondly, you need to expand the code of good practice 2 a little bit.
try
{
code = readData();
if (code == null) continue;
lastRead = System.currentTimeMillis();
// whenever you receive the heart beat reply, just ignore it.
if (MSG_HEARTBEAT.equals(code)) continue;
// todo: handle other messages
}
catch (SocketTimeoutException ste)
{
// in a typical situation the soTimeout is about 200ms
// the heartbeat interval is usually a couple of seconds.
// and the heartbeat timeout interval a couple of seconds more.
if ((heartbeatTimeoutInterval > 0) &&
((System.currentTimeMillis() - lastRead) > heartbeatTimeoutInterval))
{
// no reply to heartbeat received.
// end the loop and perform a reconnect.
break;
}
}
You need to decide if your client or server should send the message. That decision is not so important. But e.g. if your client sends the message, then your client will need an additional thread to send the message. Your server should send a reply when it receives the message. When your client receives the answer, it should just continue (i.e. see code above). And both parties should check: "how long has it been?" in a very similar way.
You could wrap a thread around the connection and have it periodically send a status to keep the line open, say every 30 seconds or whatever. Then, when it actually has data to send it would reset the keep alive to be 30 seconds after the last transmission. The status could be helpful to see if the client is still alive anyway, so at least it can be a useful ping.
Also, you should change your server code, you appear to only handle one connection at the moment. You should loop and when a socket connection comes in spawn a thread to handle the client request and go back to listening. I may be reading to much into what may just be your test code, though.
Make the client socket connection wrapped around a thread. Use a blocking queue to wait for messages. There should only be a single sender queue throughout your application, so use a singleton pattern.
e.g.
QueueSingleton queue = QueueSingleton.getSenderQueue();
Message message = queue.take() // blocks thread
send(message); //send message to server
When you need to send a message to the server, you can use the blocking queue to send the message.
QueueSingleton queue = QueueSingleton.getSenderQueue();
queue.put(message)
The client thread will wake up and process the message.
For maintaining the connection, use a timer task. This is special type of thread that calls a run method repetitively at specified periods. You can use this to post a message, a ping message, every so often.
For processing the received message, you could have another thread, waiting for messages on another blocking queue (receiver queue). The client thread will put the received message on this queue.
Say I have a socket variable called SuperSocket is there any way that I can catch the timeout exception ?
SuperSocket.setSoTimeout(5000);
catch (SocketTimeoutException e){
System.out.println("Timeout");
System.exit(1);
}
You seem to not understand what setSoTimeout() does and when that exception would be thrown.
From the Javadoc: ( http://docs.oracle.com/javase/6/docs/api/java/net/Socket.html )
public void setSoTimeout(int timeout)
throws SocketException
Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds.
With this option set to a non-zero timeout, a read() call on the
InputStream associated with this Socket will block for only this
amount of time. If the timeout expires, a
java.net.SocketTimeoutException is raised, though the Socket is still
valid. The option must be enabled prior to entering the blocking
operation to have effect. The timeout must be > 0. A timeout of zero
is interpreted as an infinite timeout.
The only time a SocketTimeoutException can be thrown (and then caught) is when you're doing a blocking read on the Socket's underlying InputStream and no data is received in the specified time (causing the read to ... time out).
superSocket.setSoTimeout(5000);
InputStream is = superSocket.getInputStream();
int i;
try {
i = is.read();
} catch (SocketTimeoutException ste) {
System.out.println("I timed out!");
}
Edit to add: There's actually one other time the exception can be thrown, and that's if you're calling the two argument version of Socket.connect() where you supply a timeout.
I wanna kill the TCP connection listener thread(serverside) after client closes the socket..
The thread waits in the loop in the readLine()..
How can i do it?
while(isconnected){
String msg = in.readLine();
//..
}
You have to call socket.close() method, if you are using it properly it should be fine. I don't know where readLine() is coming from, so I will assume its BufferedReader. If you look here in the documentation BufferedReader readLine()
you will see that it throws IOException if there is an error and if it is end of stream it will return null.
so you should basically do this:
try{
while(socket.isConnected()){
String line = in.readLine();
if(line==null){
//END OF STREAM
}
}
}catch(IOException e){
//deal with IOException here
}
otherwise, what I assume your currently doing is sitting in a tight loop as soon as the other end disconnects. If you try too print out msg in your above code you will see it print out null nonstop.
Perhaps extend your protocol so that the client sends a QUIT message before closing its socket.
First, you can't tell if the client is just taking a long time to respond, or if it is down.
What you can do is set some timeout period and have a thread in the server that calls clientSocket.close() after the timeout has elapsed. This will throw a SocketException in the receiving thread. It will take you out of the receiving loop and the thread will just terminate by itself if there is nothing after the receiving loop.
WalterM is basically right. The readLine call will return null is the stream is closed by the remote client, and will throw an exception if the connection "breaks" without a proper close, or the low-level socket read times out.
It is worth pointing out that it is simpler and more efficient to just do this:
try {
String msg;
while ((msg = in.readLine()) != null) {
// do stuff
}
} catch (IOException ex)
// report error
} finally {
// Close the socket under all circumstances to avoid potential
// resource leakage
try {
socket.close();
} catch (IOException ex) {
// ignore
}
}
Checking that the socket is still connected it redundant. The low-level socket read will be doing that anyway.
You'll need to interrupt the thread.
I am trying to read input from a socket line by line in multiple threads. How can I interrupt readLine() so that I can gracefully stop the thread that it's blocking?
EDIT (bounty): Can this be done without closing the socket?
Without closing the socket:
The difficult problem isn't the BufferedReader.readLine, but the underlying read. If a thread is blocked reading, the only way to get it going is to supply some actual data or close the socket (interrupting the thread probably should work, but in practice does not).
So the obvious solution is to have two threads. One that reads the raw data, and will remain blocked. The second, will be the thread calling readLine. Pipe data from the first the second. You then have access to a lock than can be used to wakeup the second thread, and have it take appropriate action.
There are variations. You could have the first thread using NIO, with a single thread instance shared between all consumers.
Alternatively you could write a readLine that works with NIO. This could even take a a relatively simple single-threaded form, as Selector.wakeup exists and works.
Close the socket on the interrupting thread. This will cause an exception to be thrown on the interrupted thread.
For more information on this and other concurrency issues, I highly recommend Brian Goetz's book "Java Concurrency in Practice".
Sorry for being over 6 years late ;-) I had a need for some interruptible readLine when reading from the keyboard, for a simple hobby console application. In other words, I couldn't "close the socket".
As you may know, System.in is an InputStream that apparently already does some buffering (you need to press Enter]). However, it seems to be suggested to wrap it in a BufferedReader for better efficiency, so my input is from:
BufferedReader consoleIn = new BufferedReader(new InputStreamReader(System.in));
The other thing one might have discovered is that BufferedReader.readLine() blocks until input is provided (even if the thread is interrupted, which seems to only end the thread once readline() gets its input). It is however possible to predict when BufferedReader.read() will not block, by calling BufferedReader.ready() == true. (However, == false does not guarantee a block, so beware.)
So I have incorporated the above ideas into a method that reads the BufferedReader character by character, checking in between each character if the thread has been interrupted, and also checks for end-of-line, at which point the line of text is returned.
You may find this code useful, pass the consoleIn variable as declared above. (Criticism may be welcomed too...):
private String interruptibleReadLine(BufferedReader reader)
throws InterruptedException, IOException {
Pattern line = Pattern.compile("^(.*)\\R");
Matcher matcher;
boolean interrupted = false;
StringBuilder result = new StringBuilder();
int chr = -1;
do {
if (reader.ready()) chr = reader.read();
if (chr > -1) result.append((char) chr);
matcher = line.matcher(result.toString());
interrupted = Thread.interrupted(); // resets flag, call only once
} while (!interrupted && !matcher.matches());
if (interrupted) throw new InterruptedException();
return (matcher.matches() ? matcher.group(1) : "");
}
... And in the thread that is calling this, catch the exceptions and end the thread appropriately.
This was tested in Java 8 on Linux.
I was playing around with this recently (using Scala), and I didn't like the accepted answer of closing the socket and getting an exception.
Eventually I discovered that it's possible to call socket.shutdownInput() in the interrupting thread to get out of the readLine call without an exception. I make this call in a SIGINT handler so that I can clean up and close the socket in the main thread.
Note, that the equivalent exists for the outputstream with socket.shutdownOutput()
you can design a Timer class around the read() block.
you need to set a timeout for your timer.
on timeout just interrupt your thread.
Without closing the socket, no question the best solution with the least overhead is to simply avoid using the blocking read methods until the BufferedReader is ready, or a timeout is reached.
public String readLineTimeout(BufferedReader reader, long timeout) throws TimeoutException, IOException {
long start = System.currentTimeMillis();
while (!reader.ready()) {
if (System.currentTimeMillis() - start >= timeout)
throw new TimeoutException();
// optional delay between polling
try { Thread.sleep(50); } catch (Exception ignore) {}
}
return reader.readLine(); // won't block since reader is ready
}
If you want to use readLine on a server socket within a client-server tcp architecture, for instance, you can use setSoTimeout(int timeout) of java.net.Socket.
From the Socket#setSoTimeout(int timeout) Documentation:
Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid.
public class MainApp {
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(10);
ServerSocket serverSocket = new ServerSocket(11370);
Socket clientSocket = serverSocket.accept();
clientSocket.setSoTimeout(2000);
executorService.execute(new ReadingThread(clientSocket));
// ... some async operations
executorService.shutdown();
}
}
public class ReadingThread implements Runnable {
private final Socket clientSocket;
public ReadingThread(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
BufferedReader socketReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String readInput = null;
while (!Thread.currentThread().isInterrupted()) {
try {
readInput = socketReader.readLine();
} catch (SocketTimeoutException e) {
continue;
}
}
// operations with readInput
}
}
The main application implements a server socket which listens to connections and has a thread pool. If an incoming client communication is accepted, then a new Thread from the pool is assigned and the run function is invoked in ReadingThread (can be adjusted to allow multiple threads).
On the socket used for communicating to the client the property setSoTimeout(int timeout) has been set. Therefore if readLine does not return within the specified timeout a SocketTimeoutException is thrown.
You can check in a loop whether the ReadingThread has been interrupted by the main application, and if so stop reading from the socket.
When the buffered reader is being used to read the input stream from a socket then you can achieve this by having the read call timeout. Once this timeout is triggered you will be able to check if your thread should be stopped. To do this call setSoTimeout on the socket. The read call will then have a SocketTimeoutException and you can use that to stop the thread.
#Override
public void run() {
running = true;
try {
socket.setSoTimeout(1000); // This will determine how quick your thread responds to the shutdown call
var inputStream = socket.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
} catch (IOException e) {
Logger.error("IOException while setting up input stream");
Logger.error(e);
return;
}
StringBuilder stringBuilder = null;
while (running) {
try {
int singleChar = bufferedReader.read();
// Do something with the data
} catch (SocketTimeoutException e) {
// SocketTimeoutException is expected periodically as we do setSoTimeout on the socket,
// this makes the above read call not block for ever and allows the loop to be interrupted
// cleanly when we want to shut the thread down.
Logger.trace("Socket timeout exception");
Logger.trace(e);
} catch (IOException e) {
Logger.error("IOException while reading from socket stream");
Logger.error(e);
return;
}
}
}
public void stopThread() {
running = false;
try {
bufferedReader.close();
} catch (IOException e) {
Logger.error("IOException while closing BufferedReader in SocketThread");
Logger.error(e);
}
}
Answer found here: Any way of using java.nio.* to interrupt a InputStream#read() without closing socket?
I think that you might have to use something other than readLine(). You could use read() and at every loop iteration check to see if the thread was interrupted and break out of the loop if it was.
BufferedReader reader = //...
int c;
while ((c = reader.read()) != -1){
if (Thread.isInterrupted()){
break;
}
if (c == '\n'){
//newline
}
//...
}
A sketch for a solution might be this: NIO provides methods for nonblocking IO, so you have to implement something called Foo that uses nonblocking NIO on the socket end but also provides a InputStream or Reader interface on the other end. If the BufferedReader enters its own read, it will call Foo, which will call Selector.select with read intent. select will either return indicating the presence of more data or it will block until more data is available.
If another thread wants to unblock the reader, it must call Selector.wakeup and the selector can return gracefully by throwing an exception the by BufferedReader.
The socket should be still open after that.
Variation A: call Selector.select(timeout) to do busy polling light.
This is a follow up to:
this question
Basically, I have a server loop that manages a connection to one solitary client. At one point in the loop, if a ClientSocket exists it attempts a read to check if the client is still connected:
if (bufferedReader.read() == -1) {
logger.info("CONNECTION TERMINATED!");
clientSocket.close();
setUpSocket(); // sets up the server to reconnect to the client
} else {
sendHeartBeat(); // Send a heartbeat to the client
}
The problem is, that once a socket has been created the application will hang on the read, I assume waiting for data that will never come, since the client never sends to the server. Before this was OK, because this correctly handled disconnects (the read would eventually fail when the client disconnected) and the loop would attempt reestablish the connection. However, I now have added the above sendHeartBeat() method, which periodically lets the client know the server is still up. If the read is holding the thread then the heartbeats never happen!
So, I assume I am testing if the connection is still up incorrectly. I could, as a quick hack, run the bufferedReader.read() in a seperate thread, but then I'll have all sorts of concurrency issues that I really don't want to deal with.
So the question is a few fold:
Am I checking for a client disconnect correctly?
If not, how should I do it?
If I am doing it correctly how I do I get the read to not hold the process hostage? Or is threading the only way?
When you create your socket, first set a timeout:
private int timeout = 10000;
private int maxTimeout = 25000;
clientSocket.setSoTimeout(timeout);
With this, if a read times out you'll get java.net.SocketTimeoutException (which you have to catch). Thus, you could do something like this, assuming you've previously set the SO_TIMEOUT as shown above, and assuming that the heartbeat will always get a response from the remote system:
volatile long lastReadTime;
try {
bufferedReader.read();
lastReadTime = System.currentTimeMillis();
} catch (SocketTimeoutException e) {
if (!isConnectionAlive()) {
logger.info("CONNECTION TERMINATED!");
clientSocket.close();
setUpSocket(); //sets up the server to reconnect to the client
} else {
sendHeartBeat(); //Send a heartbeat to the client
}
}
public boolean isConnectionAlive() {
return System.currentTimeMillis() - lastReadTime < maxTimeout;
}
A common way of handling this is setting the timeout to some number (say 10 seconds) and then keeping track of the last time you successfully read from the socket. If 2.5 times your timeout have elapsed, then give up on the client and close the socket (thus sending a FIN packet to the other side, just in case).
If the heartbeat will not get any response from the remote system, but is just a way of ultimately generating an IOException earlier when the connection has fallen down, then you could do this (assuming that the sendHeartBeat itself will not throw an IOException):
try {
if (bufferedReader.read() == -1) {
logger.info("CONNECTION TERMINATED with EOF!");
resetConnection();
}
} catch (SocketTimeoutException e) {
// This just means our read timed out ... the socket is still good
sendHeartBeat(); //Send a heartbeat to the client
} catch (IOException e) {
logger.info("CONNECTION TERMINATED with Exception " + e.getMessage());
resetConnection();
}
....
private void resetConnection() {
clientSocket.close();
setUpSocket(); //sets up the server to reconnect to the client
}
You are checking correctly, you can should add a try catch with IOException in case it occurs.
There is a way to avoid threading, you can use a Selector with a non-bloking socket.
public void initialize(){
//create selector
Selector selector = Selector.open();
ServerSocketChannel acceptSocket = ServerSocketChannel.open();
acceptSocket.configureBlocking(false);
String bindIp = "127.0.0.1";
int bindPort = 80;
acceptSocket.socket().bind(new InetSocketAddress(bindIp, bindPort));
//register socket in selector for ACCEPT operation
acceptSocket.register(selector, SelectionKey.OP_ACCEPT);
this.selector = selector;
this.serverSocketChannel = serverSocketChannel;
}
public void serverStuff() {
selector.select(maxMillisecondsToWait);
Set<SelectionKey> selectedKeys = selector.selectedKeys();
if( selectedKeys.size() > 0 )
{
if( key.isAcceptable() ){
//you can accept a new connection
SocketChannel clientSk = serverSocketChannel.accept();
clientSk.configureBlocking(false);
//register your SocketChannel in the selector for READ operations
clientSk.register(selector, SelectionKey.OP_READ);
} else if( key.isReadable() ){
//you can read from your socket.
//it will return you -1 if the connection has been closed
}
}
if( shouldSendHeartBeat() ){
SendHeartBeat
}
}
You should add error checking in your disconnection detection. Sometimes an IOException may be thrown when the connection to the other end is lost.
I am afraid that threading is unavoidable here. If you don't want to block the execution of your code, you need to create a separate thread.