time out for InetSocketAddress - java

I have the following code:
socket.connect(new InetSocketAddress(serverHost, serverPort), CONNECT_TIMEOUT);
The problem is that when the DNS is not accessible the InetSocketAddress takes 45sec to timeout and return an exception ("Host in not accessible...").
I need the entire command (so the creation of InetSocketAddress and the connect to timeout earlier. I did not find a way to make the new InetSocketAddress(serverHost, serverPort) timing out earlier.
Is it possible?
PS
I'm on Android but the problem is the same on other platform

There is no easy way. You need to run this code
socket.connect(new InetSocketAddress(serverHost, serverPort), CONNECT_TIMEOUT);
in a separate thread (i/o thread) and communicate with it from UI main thread. Once you are over your time limit - send it a terminate signal and proceeding in UI thread immediately, don't wait till it does terminate. Depending on the state, the i/o thread either dies immediately or eventually.

Related

Java: Re-use ports before linux OS puts them into TIME_WAIT

I am trying to build a java multi threaded server using a thread pool. I have limited the number of threads to perform my actions to 15 but every time the server socket accepts a new connection it creates the connection on a new port, once the thread is complete it closes the socket however linux puts the port into a TIME_WAIT state. This server receives a lot of traffic and because of the wait it quickly runs out of available ports and hangs until the timed wait expires. I do not have root access to change the time wait time so is there a way to re-use ports instead of putting them into TIME_WAIT?
public static void main(String argv[]) throws Exception{
init_LogServer.initMarshal();
ServerSocket socket = new ServerSocket(44431);
ConcurrentHashMap<Integer, String> transactionMap = new ConcurrentHashMap<Integer,String>();
CountTrans Tracker = new CountTrans(transactionMap);
ExecutorService executor = Executors.newFixedThreadPool(15);
System.out.println("Waiting...");
//listen for log packets
while(true){
//open socket
Socket connectionSocket = socket.accept();
//send to thread
Runnable worker = new LogThread(connectionSocket, Tracker);
executor.execute(worker);
}
}
The way to stop TIME_WAITs piling up at the server is to be the one that receives the close first. That simply means that you should adjust your socket handling code to loop, instead of just processing a single request/response pair. When the client closes the socket, you will detect end of stream instead of a new request, close the socket, and exit the handler. Closing the socket after the client has already done so means that TIME_WAIT happens at the client end.
As another benefit, you can then implement connection-pooling at the client.
No, if you can't change the TIME_WAIT time you can't change the TIME_WAIT time.
If you could, you might run into problems because the idea of the TIME_WAIT state is to stop any stray packets from this connection from interfering with the next connection.
I suppose you'll have to get another IP address or make less connections.

How to terminate a server socket thread on timeout?

I'm using Spring Integration on the server side to offer a socket. The socket as a defined soTimeout, so that exceeding that timeout will close the current open socket connection to the client.
TcpConnectionFactoryFactoryBean fact = new TcpConnectionFactoryFactoryBean();
fact.setSoTimeout(timeout);
But the thread on the server side will continue. How can I force cancelation/termination of the server socket as well (maybe with an additional thread timeout, so that no thread can hang in the background by any issues)?
I presume you mean you want to stop listening for new connections when one of the client connenctions times out.
Implement ApplicationListener for TcpConnectionExceptionEvent and examine the exception; if it's a SocketTimeoutException, call close() on the server factory that was created by the factory bean.

Waiting for ServerSocket accept() to put socket into "listen" mode

I need a simple client-server communication in order to implement unit-test.
My steps:
Create server thread
Wait for server thread to put server socket into listen mode ( serverSocket.accept() )
Create client
Make some request, verify responses
Basically, I have a problem with step #2. I can't find a way to signal me when server socket is put to "listen" state. An asynchronous call to "accept" will do in this case, but java doesn't support this (it seems to support only asynchronous channels and those are incompatible with "accept()" method according to documentation).
Of cause I can put a simple "sleep", but that is not really a solution for production code.
So, to summarize, I need to detect when ServerSocket has been put into listen mode without using sleeps and/or polling.
The socket is put into listening state as soon as you construct the ServerSocket object, not when you call accept. As long as you create the client after the ServerSocket constructor has completed, you won't have a problem. Connections will be accepted and internally queued until accept gets called.
Here is some code to demonstrate:
ServerSocket serverSocket = new ServerSocket(12345);
Thread.sleep(10000);
Socket socket = serverSocket.accept();
During that 10 second gap before accept is called, the OS netstat command will show the server socket in "LISTENING" state, and clients can connect to it. If a client connects during that 10 seconds, the connection is queued, and when the accept method is finally called it immediately returns the queued Socket object.
Why not to send single just before calling accept()?
connectionAccepted = true;
loc.notify();
socket.accept();
To be sure that the socket is ready add a tiny sleep in your "client" code:
wait();
// we are here when notify is called.
Thread.sleep(10); // 10 ms
startTest();
You can even do better: create loop that tries to "ping" the socket with a tiny sleep between attempts. In this case you will start test as quickly as it is possible.

How to unblock a thread blocked on ServerSocket.accept()?

I have a server thread with this code:
public void run() {
try {
ServerSocket server;
EneaLog.printLog("Server is running.");
server = new ServerSocket(this.portnumber);
while (true) {
new EneaServerConnection(server.accept(), this.project,stopped).start();
if (stopped) {
EneaLog.printLog("Server safe-shutdown completed.");
EneaLog.printLog("Hi!");
server.close();
return;
}
}
} catch (IOException ex) {
Logger.getLogger(EneaServer.class.getName()).log(Level.SEVERE, null, ex);
project.getExceptionHandler().handler(ex);
}
}
and a shutdown method like this:
public void shutdown() {
EneaLog.printLog("Server shutdown NOW!");
stopped = true;
}
I want that shutdown can unblock thread that are waiting on server.accept() otherwise I must wait for connection before server shutdown.
I can't do server.close() in shutdown() because I must signal to registered client that server is coming down.
Any ideas?
I try to design my code so that it can be "shutdown" with an interrupt. Mainly, this is because the Executor framework in Java's concurrency package uses interrupt to cancel running tasks. Also, the "shutdown" task doesn't have to know any internals of the task being killed.
However, a call to accept will not respond to an interrupt unless it is created from a ServerSocketChannel. A server created with a ServerSocket constructor will ignore interrupts, and I haven't found a way to reconfigure this.
If you can't change the code that creates the server, arrange for another thread to call close on the server socket. This will also raise an exception in thread blocked on accept, regardless of the method used to create the server socket.
This turns out to be a really big pain when using SSL. A JSSE socket is not created from an InterruptibleChannel, and won't respond to a simple interrupt on the thread.
I just noticed that the question says that the server can't be closed without notifying the client. Successfully interrupting a socket results in its closure.
On a call to accept this shouldn't be a problem, since the client is not connected if the server socket is blocked in accept. That should only be an issue for Socket instances, that represent current connections.
If that doesn't satisfy the notification requirements, a rework to use NIO's ServerSocketChannel in non-blocking mode may be necessary.
You should be able to close the socket from another thread.
Neither interrupt (that's dependent on interrupt points in the same way cancellation is dependent on cancellation points) nor close will do it (accept does not responsed to closing its file descriptor). You'll have to communicate with the accept (try sendto, with a shutdown notification) to notify it to not continue accepting. At least this is the case on linux; don't know what it's like on other platforms.
I've been faced to the same problem. My working solutions consists into closing the ServerSocket object (serverSocket.close()) ; doing this will cause the accept() method to throw a SocketException, which is what you want to do.
Vincent
Have you tried Thread.interrupt() ?
If this thread is blocked in an I/O
operation upon an interruptible
channel then the channel will be
closed, the thread's interrupt status
will be set, and the thread will
receive a ClosedByInterruptException.
If this thread is blocked in a
Selector then the thread's interrupt
status will be set and it will return
immediately from the selection
operation, possibly with a non-zero
value, just as if the selector's
wakeup method were invoked.

java/groovy socket write timeout

I have a simple badly behaved server (written in Groovy)
ServerSocket ss = new ServerSocket(8889);
Socket s = ss.accept()
Thread.sleep(1000000)
And a client who I want to have timeout (since the server is not consuming it's input)
Socket s = new Socket("192.168.0.106", 8889)
s.setSoTimeout(100);
s.getOutputStream.write( new byte[1000000] );
However, this client blocks forever. How do I get the client to timeout?
THANKS!!
You could spawn the client in it's own thread and spin lock/wait(timeout long) on it to return. Possibly using a Future object to get the return value if the Socket is successful.
I do believe that the SO_TIMEOUT setting for a Socket only effects the read(..) calls from the socket, not the write.
You might try using a SocketChannel (rather then Stream) and spawn another thread that also has a handle to that Channel. The other thread can asynchronously close that channel after a certain timeout of it is blocked.
The socket timeout is at the TCP level, not at the application level. The source machine TCP is buffering the data to be sent and the target machine network stack is acknowledging the data received, so there's no timeout. Also, different TCP/IP implementations handle these timeouts differently. Take a look at what's going on on the wire with tcpdump (or wireshark if you are so unfortunate :) What you need is application level ACK, i.e. you need to define the protocol between client and the server. I can't comment on Java packages (you probably want to look at nio), but receive timeout on that ACK would usually be handled with poll/select.
There is no way to get the timeout, but you can always spawn a thread that closes the connection if the write hasn't finished.

Categories

Resources