My problem is that the ServerSocket.accept() command keeps waiting until a client has connected to it. But what I want to do is that I have to listen for a client for a few seconds. If a client connects, then I send data to the client otherwise I have to terminate the ServerSocket.
So how do I bypass the ServerSocket.accept() command when no client has connected for some time?
Call ServerSocket.close() (from another thread of course). SocketException will be thrown for any thread blocking on accept(), but if a connection has been made, then existing Socket is still fine.
A simple and naive example
ServerSocket ss = new ServerSocket(8123);
new Thread() {
#Override
public void run() {
try {
Thread.sleep(5000);
ss.close();
} catch(InterruptedException e) {
} catch(IOException e) {
}
}
}.start();
Socket s = ss.accept();
Related
So my program has clients that are entering tasks and they can see each other tasks but i want the server to close when all the clients are shutdown by a command and i don't want to look for more clients after the last one closes.
What i have tried is counting the number of clients that entered and when there is none, the problem is that the server tries to accept new clients and does't check the condition can any one help me?
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(4242);
while (acceptNewClients) {
Socket clientSocket = serverSocket.accept();
countClient++;
System.out.println(countClient);
ThreadedServer clientThread = new ThreadedServer(clientSocket);
new Thread(clientThread).start();
if (countClient == 0) {
flipAcceptNewClients();
}
}
}catch (IOException e) {
e.printStackTrace();
}
If you want to shut down the server, call System.exit(0); to do so.
interrupting the thread that is blocking on serverSocket.accept() may or may not work; depends on the OS and JVM, hence, that's not a great way to do this.
I'm trying to create a multi threaded server to which multiple clients can connect and can be served. However, I'm not sure on how to properly free up my resources should the need arise.
My server runs an input thread (waiting for user inputs) and a procressing thread (handles connections and users). I open up a ServerSocket in the server class and pass it to my processing thread. It looks like this:
public class ClientConnector implements Runnable {
private ServerSocket serverSocket;
public ClientConnector(ServerSocket serverSocket) {
this.serverSocket = serverSocket;
}
#Override
public void run() {
ExecutorService tcpExecutor = Executors.newCachedThreadPool();
while (!serverSocket.isClosed()) {
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("could not accept connection");
}
if (clientSocket != null) {
tcpExecutor.execute(new ClientHandler(clientSocket);
}
}
}
}
If I want to exit, I just run this method in my server class to close the ServerSocket:
public void exit() {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Which should cause the next serverSocket.accept() call to throw an exception, and the loop stops since the socket is closed.
My question is - does closing a ServerSocket implicitly close ClientSockets that were created using it? Or should I make sure to close every single open ClientSocket by hand? If so, is there an easy way to do so instead of saving every single connection made to the server somewhere?
does closing a ServerSocket implicitly close ClientSockets that were created using it?
No, it has no effect on them.
Or should I make sure to close every single open ClientSocket by hand?
Yes, and you should be doing that anyway, in every handler thread.
If so, is there an easy way to do so instead of saving every single connection made to the server somewhere?
Just impose a read timeout and close each socket that times out. This is a normal part of any server. You don't have to collect the sockets or take any special measures about them for shutdown.
Let the client handler thread, closes the client socket on the end of processing.
I'm trying to create a multi threaded server to which multiple clients can connect and can be served. However, I'm not sure on how to properly free up my resources should the need arise.
My server runs an input thread (waiting for user inputs) and a procressing thread (handles connections and users). I open up a ServerSocket in the server class and pass it to my processing thread. It looks like this:
public class ClientConnector implements Runnable {
private ServerSocket serverSocket;
public ClientConnector(ServerSocket serverSocket) {
this.serverSocket = serverSocket;
}
#Override
public void run() {
ExecutorService tcpExecutor = Executors.newCachedThreadPool();
while (!serverSocket.isClosed()) {
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("could not accept connection");
}
if (clientSocket != null) {
tcpExecutor.execute(new ClientHandler(clientSocket);
}
}
}
}
If I want to exit, I just run this method in my server class to close the ServerSocket:
public void exit() {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Which should cause the next serverSocket.accept() call to throw an exception, and the loop stops since the socket is closed.
My question is - does closing a ServerSocket implicitly close ClientSockets that were created using it? Or should I make sure to close every single open ClientSocket by hand? If so, is there an easy way to do so instead of saving every single connection made to the server somewhere?
does closing a ServerSocket implicitly close ClientSockets that were created using it?
No, it has no effect on them.
Or should I make sure to close every single open ClientSocket by hand?
Yes, and you should be doing that anyway, in every handler thread.
If so, is there an easy way to do so instead of saving every single connection made to the server somewhere?
Just impose a read timeout and close each socket that times out. This is a normal part of any server. You don't have to collect the sockets or take any special measures about them for shutdown.
Let the client handler thread, closes the client socket on the end of processing.
Im creating a server client program where client sends certain information to the server and get according response from the server.
For continuously listening from multiple clients I have a thread in server which continuously listens client request. whenever a request is received I start another thread and send that socket to run and start listening for other clients request.
here is the code for continuously listening
while(true){
//serverListener is a ServerSocket object
clientSocket = serverListener.accept();//Waiting for any client request
//New thread started when request is received from any client
Thread thread =new Thread(new serverThread(clientSocket), "ClientThread");
thread.start();
}
Now my problem is that how can i stop the server. I know one alternative of using a boo lean variable in while loop and then changing the value, but the problem is when where thread is in waiting to get any connection at that time changing value of the boolean variable will also not stop the server.
Is there any way to solve this problem.
Typically the serverListener (which I assume is actually a ServerSocket or something) is closed by another thread. This will generate a java.net.SocketException in accept() which will terminate the loop and the thread.
final ServerSocket serverSocket = new ServerSocket(8000);
new Thread(new Runnable() {
public void run() {
while (true) {
try {
serverSocket.accept();
} catch (IOException e) {
return;
}
}
}
}).start();
Thread.sleep(10000);
serverSocket.close();
ServerSocket#setSoTimeout() may of your interest, that will abandon accept if a timeout was reached. Be aware of catch the SocketTimeoutException.
volatile boolean finishFlag = false;
while(true){
clientSocket = serverListener.accept();//Waiting for any client request
if ( finishFlag )
break;
//New thread started when request is received from any client
Thread thread =new Thread(new serverThread(clientSocket), "ClientThread");
thread.start();
}
EDIT:
for interrupting listener, you should stop this thread from outside, and then accept( ) will throws IOException
try {
while (true) {
Socket connection = server.accept( );
try {
// any work here
connection.close( );
}
catch (IOException ex) {
// maybe the client broke the connection early.
}
finally {
// Guarantee that sockets are closed when complete.
try {
if (connection != null) connection.close( );
}
catch (IOException ex) {}
}
}
catch (IOException ex) {
System.err.println(ex);
}
In my Server application I'm trying to handle the Server which is using ServerSocket like,
Start the server and wait for connection.
Stop the server which is connected with a client.
Stop the server which is waiting for a client.
I can able to start the server and make it to wait for client inside a thread using
socket = serverSocket.accept();
What I want to do is I want manually close the socket which is waiting for connection, I have tried using,
if (thread != null) {
thread.stop();
thread = null;
}
if (socket != null) {
try {
socket.close();
socket = null;
}
catch (IOException e) {
e.printStackTrace();
}
}
After executing the above code even though the socket becomes null, when I try to connect from client to server, the connection gets established, so my question is how to interrupt the serversocket which listening for connection over here,
socket = serverSocket.accept();
I think a common way of handling this is make the accept() call time out in a loop.
So something like:
ServerSocket server = new ServerSocket();
server.setSoTimeout(1000); // 1 second, could change to whatever you like
while (running) { // running would be a member variable
try {
server.accept(); // handle the connection here
}
catch (SocketTimeoutException e) {
// You don't really need to handle this
}
}
Then, when you wanted to shut down your server, just have your code set 'running' to false and it will shut down.
I hope this makes sense!
Just close the ServerSocket, and catch the resulting SocketClosedException.
And get rid of the thread.stop(). For why, see the Javadoc.