I have this socket implementation in java which uses timeout:
try {
socket = new Socket();
socket.connect(new InetSocketAddress(ip, port), 5000);
} catch (SocketException e2) {
System.out.println("Something wrong with the socket: " + e2);
}
The ip and port is closed, so connection cannot be made.
But the timeout here does not work. It does not wait for 5 seconds and then return an error.
This code is located in constructor and calls from runnable class. May this be the reason?
The connect timeout is the maximum time that connect() will block for. If there is an immediate connection refusal or other error, you will get it immediately. In this case the target port wasn't listening so you would have got an immediate ConnectException: connection refused. It isn't obliged to wait for the timeout if the error happens sooner. The timeout is really for where there is no response at all. Waiting after an error doesn't make any sense.
Socket socket = new Socket();
// This limits the time allowed to establish a connection
// timeout takes place if connection result is not received with in the specified timeout.
socket.connect(new InetSocketAddress(host, port), timeout);
// This stops the request for waiting for response after connection succeeds.
socket.setSoTimeout(timeout);
Related
I have a ServerSocket waiting to accept connections. Upon receiving a certain event on another thread, I close the socket so it no longer waits for connections. I receive a java.net.SocketException with "Socket closed" message. The problem is, how to identify the "Socket closed" exception. I can use the exception message to do this, but I feel it's not how I should handle exceptions.
I looked up the documentation:
https://docs.oracle.com/javase/9/docs/api/java/net/SocketException.html
There are a number of subclasses to the SocketException class, but I couldn't find anything that refers to the "Socket closed" thing. Is it ok to use the exception message to identify it? Could this message ever change, maybe on another platform or something?
Here's some code:
try {
// Wait for connection,
connectionSocket = serverSocket.accept();
} catch (SocketException e) {
// How to identify the "Socket closed" exception?
// ...
} catch (IOException e) {
e.printStackTrace();
}
The better way to do this is:
Define a 'stop' flag.
Set it when you want the server to stop accepting.
Set a shortish socket timeout on the server socket, say a few seconds.
When you get a connection or incur the timeout, check the flag, and proceed accordingly.
I'm developing an application on android studio. I'm trying to open a socket connection.
When the user enters the right IP address, everything works fine, but if the address is not the right IP, the Socket is not connected.
But the problem is that the Socket does not throw an catch Exception, the app is running and now if the user enters the right ip address, the socket is not connected.
My question is why it does not throw an catch Exception if the IP address is not the right IP and how can I make it work?
Here is the code
try {
sockettcp = new Socket(Address, Port);
} catch (Exception e) {
valid = false;
}
Normal way of Socket is that it tries to connect to the given IP on the given Port.
If for some reason the IP is not the right one, the Socket will not throw an err, instead it will "timeout" trying to reconnect every minute or so (Main thread or the GUI thread).
The 4 errors that are Thrown by this type of constructor public Socket(String host, int port) are:
IOException //- if an error occurs during the connection
SocketTimeoutException //- if timeout expires before connecting
IllegalBlockingModeException //- if this socket has an associated channel, and the channel is in non-blocking mode
IllegalArgumentException //- if endpoint is null or is a SocketAddress subclass not supported by this socket
To "Fix" your problem, you can set the timeout to your value (this cannot exceed the platform default)
Socket sck = new Socket();
sck.connect(new InetSocketAddress(ip, port), timeout);
To "Check" if your Socket is connected, you could try this:
Socket.isConnected(); //Returns the connection state of the socket.
Note: Closing a socket doesn't clear its connection state, which means this method will return true for a closed socket (see isClosed()) if it was successfully connected prior to being closed.
See the javadoc for more info about theSocket.
I'm trying to implement a server that accepts connections but times out and closes that specific connection only if it hasn't received anything from that connection after N milliseconds.
From my possible misunderstanding of ServerSocket's setSoTimeout(int milliseconds) method, I thought this behaviour could be accomplished by passing N to setSoTimeout.
What I'm experiencing is once a client makes a connection, and doesn't send anything over that connection for N seconds, the server catches a SocketTimeoutException, but then completely stops execution and ends the process running the server program. Here is my server's listen method:
private static void listen() throws IOException {
while(true) {
try {
Socket clientSocket = serverSocket.accept();
Connection connexion = new Connection(clientSocket);
connexion.start();
} catch (SocketTimeoutException e) {
System.out.println("Socket timed out!");
break;
}
}
}
I successfully catch the SocketTimeoutException, ignore it (bad I know!) and assume that the client connection that caused the exception gets closed. Then I just break out of the catch block to continue accepting other client connections. What am I missing here?
You need to add continue; instead of break; in the try-catch clause. The server will keep listening.
assume that the client connection that caused the exception gets closed.
Incorrect assumption. The accept() is what has timed out. The client connection hasn't done anything yet.
Then I just break out of the catch block to continue accepting other client connections.
Err, no, you break out of the catch block to stop accepting other client connections. You're breaking out of the accept loop.
What am I missing here?
A continue instead of a break.
If you don't care about the SocketTimeoutException why are you setting a socket timeout on the ServerSocket? Just remove that.
I am writing an application that streams data that clients can then listen to and receive. However I am running into an issue with closing a socket when a client is no longer listening.
What I do is create a ServerSocket, when then waits for a connection and once it is connected, I start streaming the data. However, once the client is no longer connected, I am stuck in a loop of streaming and cannot tell if anyone is listening. Is there a way around this?
try {
serverSocket = new ServerSocket(STREAM_PORT);
Socket clientSocket = serverSocket.accept();
PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(), true);
while (true) {
pw.println("some data");
}
} catch (SocketException e) {
// Never occurs when client disconnects
} catch (IOException e) {
// Never occurs when client disconnects
}
I have tried using socket.isClosed(), but it always returns false. Am I approaching this from the wrong angle, or is there a way to do it. I would ideally not want the client to have to send the server a "end" command.
EDIT: Edited to reflect what current code I am running after #Rod_Algonquin suggestion
As you are using PrintWriter, which swallows I/O exceptions, you need to call checkError() after each write to see if an error has occurred.
I am trying to set the timeout of a connection on the client socket in Java. I have set the connection timeout to 2000 milliseconds, i.e:
this.socket.connect(this.socketAdd, timeOut);
This I am trying on a web application. When a user makes a request, I am passing values to socket server, but if I don't receive any response in 5 secs the socket should disconnect.
But in my case the whole request is getting submitted once again. Can any one please tell me where am I going wrong?
I want to cut the socket connection, if I don't get any response in 5 secs. How can I set it? Any sample code would help.
You can try the follwoing:
Socket client = new Socket();
client.connect(new InetSocketAddress(hostip, port_num), connection_time_out);
To put the whole thing together:
Socket socket = new Socket();
// This limits the time allowed to establish a connection in the case
// that the connection is refused or server doesn't exist.
socket.connect(new InetSocketAddress(host, port), timeout);
// This stops the request from dragging on after connection succeeds.
socket.setSoTimeout(timeout);
What you show is a timeout for the connection, this will timeout if it cannot connect within a certain time.
Your question implies you want a timeout for when you are already connected and send a request, you want to timeout if there is no response within a certain amount of time.
Presuming you mean the latter, then you need to timeout the socket.read() which can be done by setting SO_TIMEOUT with the Socket.setSoTimeout(int timeout) method. This will throw an exception if the read takes longer than the number of milliseconds specified. For example:
this.socket.setSoTimeout(timeOut);
An alternative method is to do the read in a thread, and then wait on the thread with a timeout and close the socket if it timesout.