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.
Related
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.
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();
I have this runnable receiver which I want to stop. but as it is a constantly receiving socket it's thread is in blocking mode.
I found that I had to stop the socket from outside the thread itself, using socket.close()
So i defined a public static socket. (which itself is bad, i guess?) then i start new threads and try stopping them with this code, (have not changed anything)
public static DatagramSocket socket;
Starting each thread seperatly works fine. but as the socket now is global, I can't stop them individually. How do I make the socket var global but individual? Or what do I need to make this possible?
public void startSls () throws SocketException{
try{
socket = new DatagramSocket(parseInt(port));
}catch (SocketException e) {
Log.e("CCSstream", e.toString());
}
slst = new Thread(new slss(port));
slst.start();
}
public void stopSls(){
socket.close();
stopSLS = true;
slst.interrupt();
runThreads1 = false;
}
If anything is unclear I can explain.
Thanks
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.
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.