How to catch a socket-timeout in Java - java

I'm writing a server with Java.net. Now i want to change some variables on socket-timeout.
I cant find a 'onTimeout' interface or something similar.
Now I'm searching for a solution for this problem.

You say you're using java.net so I'm assuming that you're using something like a java.net.ServerSocket. If you call setSoTimeout on your instance of ServerSocket, you will be able to set a timeout for your socket. Then, when you block during calls to accept, your ServerSocket will keep track of the timeout. As you can see in the documentation, accept throws a SocketTimeoutException if a timeout has been defined and the wait time has exceeded the timeout. So, you'll end up with something like this (forgive me for being a bit rusty on Sockets):
try(ServerSocket ssock = new ServerSocket(...))
{
ssock.setSoTimeout(10_000); // 10 second timeout
while(true)
{
Socket csock = ssock.accept();
methodToStartThreadThatHandlesClientSocket(csock);
}
}
catch(SocketTimeoutException ste)
{
//handle socket timeout
}
catch(Exception other)
{
//handle other exceptions
}

Related

DatagramSocket.receive() and SocketException

I have a thread whose job is to sit on a DatagramSocket, listen for incoming packets, and place them into a queue for further processing. Its run method is:
public void run() {
while(!disconnected) {
byte[] buffer1 = new byte[FrameSizeBytes];
DatagramPacket RxPacket = new DatagramPacket(buffer1,buffer1.length);
try {
RxSocket.receive(RxPacket);
} catch (IOException e) {
// handle exception
}
buffer1 = RxPacket.getData();
Q.add(buffer1);
}
}
I have another thread whose job it is to decide when to terminate this thread.
It does this by setting the disconnected variable to true, and closing the socket.
The idea was that closing the socket would unblock the thread into an exception; the exception could be handled; and once the exception was handled the loop condition would cause the loop to exit. (Alternatively, the exception handling itself could set disconnected to true.)
Problem: The exception thrown in this condition is a SocketException: socket closed which makes perfect sense. But DatagramSocket.receive() doesn't throw SocketExceptions, and therefore I can't handle it or throw it.
Question: Is there some way to get this idea to work, or do I need to find another approach? (Note: I don't just want to set a timeout on the socket. That's not a good approach for this application.)
Set the flag, send yourself a dummy packet, then close the socket. After receive(), check the flag before processing the packet,

Can't detect disconnect without extra readLine() loop

I am developing a program that uses sockets and currently I have a function in my code that checks for a heartbeat from the client every second.
private void userLoop() { // checks for incoming data from client
Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
try {
socketIn.read(); // check for heartbeat from client
String userInput;
while ((userInput = br.readLine()) != null) {
}
} catch (Exception e) {
ControlPanel.model.removeElement(getUsername());
ControlPanel.append(getUsername() + " has disconnected.");
}
}
}, 1000);
}
When a client closes the game via the X button, shutting off their computer, logging out, whatever it may be, I get the message "'username' has disconnected". This is exactly what I want, however, it only works with the while loop in the code. The while loop essentially does nothing and I have no idea why it doesn't work with out.
If I remove the while loop and I disconnect using my client nothing gets printed out server sided.
String userInput;
while ((userInput = br.readLine()) != null) {
}
The above is essentially the dead code that does nothing but without it my program doesn't work the way it should..
Why is the code needed and how can I remove it and still make my program work correctly?
In this case, your while loop is essentially stalling your program until you no longer receive an input string. It's not dead code; it is just your way of installing a wait.
Otherwise, based on my understanding in the Timer class, it only waits one second, which might be too short of a timespan for what you're waiting to capture.
I fixed my problem by changing everything in the try block with
br.readLine();
There's a saying I've heard about exception handling: "Exceptions should only be used for exceptional situations." A client disconnecting from a server is not exceptional.
Now that I have that off my chest, let's move on. According to this other question,
socket.getInputSteam.read() does not throw when I close the socket from the client
it sounds like the read call won't throw if you're closing things properly on the client side.
The problem is that when the remote socket is closed, read() does not throw an Exception, it just returns -1 to signal the end of the stream.
The following should work without needing to call readLine():
try {
int ret = socketIn.read(); // check for heartbeat from client
if (ret == -1) {
// Remote side closed gracefully
clientDisconnected();
}
} catch (SocketTimeoutException e) {
// Timeout -- handle as required
handleTimeout();
} catch (IOException e) {
// Connection lost due to I/O error
clientDisconnected()
}

Java: Using variables from try blocks

So I've got a thing like this:
try{ServerSocket acceptor = new ServerSocket(4782);}
catch(IOException e){System.err.println("ERROR: Couldn't listen on port 4782!");}
while (true)
{
Socket clientSock = acceptor.accept();
}
But when trying to assign clientSock, it says it can't find acceptor. When moving the acceptor out of the try block, it explodes with an unhandled exception.
Should I be putting a thing like Socket clientSock; before the try block?
Thanks.
An alternative to what the other folks here have suggested: you could move more code into the try block:
try{
ServerSocket acceptor = new ServerSocket(4782);
while (true) {
Socket clientSock = acceptor.accept();
}
} catch(IOException e){
System.err.println("ERROR: Network problem:" + e.getMessage());
}
The advantage of doing things this way -- when you can get away with it -- is that the "happy path" reads more clearly; it's easier to follow what the code is supposed to do. The dark side of this approach is that it leads to lumping various error conditions together, so you can't react as specifically to individual problems. Sometimes, though, even that is an advantage rather than a problem.
You can keep the instantiation in the try-catch but move the variable declaration out.
ServerSocket acceptor = null;
try{acceptor = new ServerSocket(4782);}
catch(IOException e){System.err.println("ERROR: Couldn't listen on port 4782!");}
while (true)
{
Socket clientSock = acceptor.accept();
}
No you should put the declarion of acceptor before the try block, like this:
ServerSocket acceptor = null;
try {
acceptor = new ServerSocket(4782);
} catch (IOException e) {
System.err.println("ERROR: Couldn't listen on port 4782!");
}
while (true) {
Socket clientSock = acceptor.accept();
}
For this code, acceptor can be null inside the while-loop, either check for it there or do something flow-alterning inside the catch-block.
You might also want to handle the IOException that Socket clientSock = acceptor.accept();
might throw, since such Exception would break the while-loop - which might not be according to plans.
The general explaination is that java scopes variable declarations "as limiting as possible" acceptor was declared inside the try-block in your code, hence not available/undeclared outside of it.

Java Exception - Socket is closed, reliable udp help?

I'm currently using a Java implementation of the Reliable UDP protocol, found [here][1]. The project has absolutely no tutorials so I have found it really hard to identify problems.
I have set up a client and server. The server runs on localhost:1234 and the client runs on localhost:1235. The server is first established, and loops listening for connections.
I then have set it to send a packet to the server. When a packet is sent, the server calls handlePacket() -
DataInputStream i = new DataInputStream(client.getSocket().getInputStream());
short packetID = i.readShort();
i = null;
switch(packetID){
case 3:
Packeta packeta = new Packeta(client);
break;
}
} catch (IOException e) {
e.printStackTrace();
}
I'm currently using a debugging with a small dummy class called Packeta. When the constructor is called, it reads from a stream and the logs to the console. However, always when constructing, it hangs for 10 seconds, before producing the error -
java.net.SocketException: Socket is closed ....
at
lessur.engine.net.packets.Packeta.(Packeta.java:15)
The constructor for Packeta -
public Packeta(LessurConnectedNode c) {
super((short)3, c);
try {
/*LINE 15*/ Logger.getLogger("adsfas").info("X was "+c.getSocket().getInputStream().read());
} catch (IOException e) {
e.printStackTrace();
}
}
It has something todo with the input streams. I don't know what is wrong, but from reading other threads, it might be todo with having multiple inputstreams. I'm lost on this, please help.
The problem was, I was passing the server to the socket listener, before the socket was fully initialized. FIXED!

Best way to recover a server from a client's disconnect

I've written a tcp server in Java. It spawns worker instances (Runnable) and listens for incoming tcp connection. Upon connection from a client, it will take in data from the client and does its own processing.
Of late, I noticed that upon client disconnection, the entire server will crash with error java.net.SocketException: Connection reset when the client disconnects or quits. This was when I realised I hadn't tested the tcp server thoroughly for all instances of failure.
I looked into the code and noticed that the tcp server will crash at this line while((bytesRead.... -1) in the worker instance
final int BUFFSIZE = 65535;
int bytesRead;
byte[] buffer = new byte[BUFFSIZE];
din = new BufferedInputStream(clientSocket.getInputStream());
while ((bytesRead = din.read(buffer)) != -1) { //tcp server crashes at this line if client quits or disconnects.
// worker does its job.
}
I've been pondering about the best way to close worker instance without causing a crash on the tcp server. I don't have access to the client source code to modify anything on their end.
Any thoughts?
Bregs
Yakult121
Network I/O should be done within a try/catch block if you want to handle exceptions.
This line should throw an IOException if the connection is closed. Just make sure to catch the IOException and return from the run() method of your Runnable when it occurs. This will stop the thread handling this client connection.
You must have done something incorrectly if it craches the whole server, though. This probably means you don't have a thread per client connection, but rather a single thread handling the clients sequentially, one at a time. Post the server code for more information.
figured out the problem. Writing down what i did for any person looking to solve the same problem.
private boolean isStopped = false;
while (!isStopped()) {
try {
while ((bytesRead = din.read(buffer)) != -1) {
// worker does its job.
}
}
catch (IOException ex) {
System.out.println("Exception called! Most likely due to client disconnect!");
stop();
}
}
public boolean isStopped() {
return this.isStopped;
}
public synchronized void stop(){
this.isStopped = true;
}

Categories