While i am running my program i have svrSocket.accept() method..My program is automatically getting terminated when it reaches to svrSocket.accept() method.
Please suggest what needs to be done.
Here is what you need to provide before we can really help you.
Stacktraces for exceptions that accept() might be throwing. If this is a simple console application look for those in the console of your IDE. There is a separate window that it runs in and shows output like this.
Is the program truly terminating? accept() is a blocking call and blocks forever until another process connects to it through the socket. Have you tried running a client that connects to your server socket to see if it un blocks and continues to run? If you have to click the stop button, if multiple run windows are open then your program is simply blocked on the accept() call and it's working as designed.
Without example code or an error message for reference, according to the API, your application may not be catching one of the following exceptions:
IOException
SecurityException
SocketTimeoutException
IllegalBlockingModeException
Also, are you sure your application terminates? The only reason I ask is accept() blocks until a connection is made.
Related
I'm interested in different approaches to gracefully shutting down a Java command line program. Sending a kill signal is not an option.
I can think of a few different approaches.
Open a port and wait for a connection. When one is made, gracefully shutdown.
Watch for a file to be created, then shutdown.
Read some input from the terminal, such as "execute shutdown".
The third one is not ideal, since there is often program output pumped to the screen. The first one takes too much effort (I'm lazy). Do most programmers use the second option? If not, what else is possible/elegant/simple?
you can try something like this:
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() { /*
my shutdown code here
*/ }
});
edit:
the shutdown hook will not perform the shutting down of the app. instead, it gives the developer a way to perform any clean-up that he/she wishes at shutdown.
from the JavaDoc for Runtime (a good read if you are planning to use this method):
A shutdown hook is simply an initialized but unstarted thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently. When all the hooks have finished it will then run all uninvoked finalizers if finalization-on-exit has been enabled. Finally, the virtual machine will halt. ...
you could try to use Runtime.getRuntime().addShutdownHook() that should satisfy your requisite. In this way you can register an hook to do cleanups, in order to perfom a gracefull shutdown.
EDIT
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)
public void addShutdownHook(Thread hook)
Registers a new virtual-machine shutdown hook.
The Java virtual machine shuts down in response to two kinds of events:
The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.
The benefit of the second option - checking for a file - over the first - listening on a port - is that you have some possibility of security.
You can set the permissions on the directory where the file is created so that only appropriate users can close the program. If you listen on a port any user can connect to it.
If you wanted to go with the socket version, it is very simple to implement. Here's the code:
ServerSocket server = new ServerSocket(8080);
System.out.println("Socket listening!");
server.accept();
System.out.println("Connection received!");
You could easily embed this code in a separate thread that you start with your program, and then have it modify global state to initiate shutdown.
The first two option is simple to implement. You could also use some JMX stuff (I don't know much about that). Tomcat uses the first approach and I applied 1 and 2 in two of my projects.
Consider having a JMX component. Then you can attach with JConsole either locally or over the network, and communicate with your component. Then the component can shut down the program properly.
With Java 6 u 10 or later, you can do the same with JVisualVM.
I would suggest to use the shutdown hook. It will allow your program do be controlled using standard OS tools. It also does not need any additional access to external resources (disk, ports, whatever).
Is there any way of preventing my application from temporarily crashing as soon as I create a socket? This program unfreezes as soon as it receives a connection but it can be misleading to users.
I have tried putting the socket creation methods etc. in a thread and running it from there but that did not work.
Edit: Unless it would be feasible to give the socket a set amount of time and then disconnect once it expires?
Running it in a separate thread is the right way, since the Socket.accept() call is blocking (i.e. it blocks the thread you call it on, until it gets a connection).
There must be something wrong with your thread architecture. Post some code and maybe I can tell You what exactly.
EDIT: Giving the socket a short timeout will either not avoid the blocking, or timeout before someone connects, while getting a connection before the timeout will not have any difference from the current setup.
You program does not crash, it is simply waiting for a connection because the java.io library is blocking.
To prevent waiting for a connection, you can either use the non-blocking java.nio classes or start a new Thread and let this new thread be the one that is waiting for the connection.
It was silly of me not to dump the stuck trace while catching the IOException from socket.accept() and shutting down the thread doing the accept... Having fixed this, I still want to understand how to deal with the situation when this call barfs.
My app is a classic socket server accepting hundreds of clients, sometimes thousands. Accepting thread is always up and blocked in accept() call. Once accepted, the separate thread gets launched to do the stuff and so on. Nothing special.
The question is, what should be done when accept() fails? Should this be considered as a permanent failure immediately? Should I retry to get into accept() for some time and try to get through? What's the best practice? And what normally the reasons for the IOException to be thrown?
Its the clients responsibility to retry on connection failure. The server should just log the exception and continue back doing "accept". Servers in general, never initiate connections to client.
There are too many reasons for IOException to be thrown, from firewall issues to file-handle-exhaustion issues. The message of the IOException should reveal the cause.
The only reasons I can think of for an IOException being thrown in accept() call would be some issue with the port being in use or the host's networking being misconfigured.
You could potentially wait a bit and retry on the assumption that the system's administrator will notice the problem and fix it. But if this happens during startup, it would be a good idea for the application to bail out with a "fatal" error message.
What I have is a multi threaded socket server listening for clients. New thread is created and started for opened connections. Clients can ask a server to execute some commands via Runtime .exec() method. Any new command received is handled by new thread (with PrintWriter passed as a parameter) and all the output (std/err) is send over the socket with PrintWriter.
The problem is that when the command takes longer (i.e. daemon) and the client disconnects for any reason I can't get the output anymore. I need to find a way of getting the output from that command execution thread on another connection (new client session which will be on another thread).
I could try to send all the output from commands to System.out and try to send it (System.out) over socket with PrintWriter (I don't know how to do this). And if I'm sucessfull maybe there is a way of sending all the such an output to every connected clients.
But then, I'm saving all the output to the database and in case of multiple clients connected I would end up having multiple inputs in my database.
Please give me some ideas as how I could go about with this issue. Thanks
You probably want to make your calls asynchronous. Executing tasks of unknown duration should never be made synchronously.
I would consider using a "reactor"-type server (i.e.: one thread per client = quick death) and using some type of message passing mechanism for long running transactions. There are a lot of middlewares that do this kind of work, it really depends on what platform you're on.
By the way, using a socket connection to execute command on a remote machine is a security flaw, but you probably already know that!
So, did you consider using a session ID for each connection? This ID will be associated with the output of each execution. So the same output could be retrieved on a subsequent call from the same user. Temporarily, the output could be stored at a repository (e.g. DB, memory, file).
Please correct me if I am not getting your question properly.
I am using Socket communication in one of my Java applications.As I know if the program meets any abnormal termination the listening ports does not get closed and the program cannot be started back because it reports "Port already open.."
Do I have anyway to handle this problem? What is the general way used to handle this matter?
It sounds like your program is listening on a socket. Normally, when your program exits the OS closes all sockets that might be open (including listening sockets). However, for listening sockets the OS normally reserves the port for some time (several minutes) after your program exits so it can handle any outstanding connection attempts. You may notice that if you shut down your program abnormally, then come back some time later it will start up just fine.
If you want to avoid this delay time, you can use setsockopt() to configure the socket with the SO_REUSEADDR option. This tells the OS that you know it's OK to reuse the same address, and you won't run into this problem.
You can set this option in Java by using the ServerSocket.setReuseAddress(true) method.
You want to set the SO_REUSEADDR flag on the socket.
See setReuseAddress().
The operating system should handle things such as that automatically, when the JVM process has ended. There might be a short delay before the port is closed, though.
As mentioned in the Handling abnormal Java program exits, you could setup a Runtime.addShutdownHook() method to deals with any special case, if it really needs an explicit operation.