In a application that I made, server accepts socket connection from clients and do various work. List of clients is stored in clients
which has a LinkedList
type.
I am using while statement with conditional statement based on size of the clients
queue.
I want to know if there is a way to solve pro开发者_如何学编程blems described below... so that server will not hang forever.
while(clients.size()>0){ //few clients the queue is alive at the moment
//Suddenly, all clients in the queue shut down at this point in the while loop,
//Another thread, which checks clients knows that clients are dead
//so clients.size() becomes 0, but there is no way to check that at this point
//and server is expecting for connection clients forever
Socket socket= server.accept();
socket.close();
}
//printout results
edit
The clients list is not just existing clients. It is a list of alive clients. This list is gets updated by another thread.
I have while statement above, because I want to do some job after there is no alive clients left. (either finished their job, or just died)
I want to solve this problem without using timeout exception, because clients will response in random time. (again, liveness of clients is checked by another Thread with heartbeat technique)
You can set the timeout on the ServerSocket
and catch the SocketTimeoutException
:
server.setSoTimeout(1000);
while (clients.size() > 0) {
try {
server.accept();
}
catch (SocketTimeoutException e) {
// Ignore
}
}
This way you will check the status of the client list every second or so.
Don't forget to synchronize access to clients
if you have other threads accessing it. Either wrap it using Collections.synchronizedList
or put appropriate synchronization in the parts of your code that access the variable.
Your loop condition doesn't make any sense to me. Why would you only be interested in accepting new clients when there are existing clients? How does this process ever get started?
But in general setting a timeout on the ServerSocket will let the accept() method throw SocketTimeoutExceptions at those intervals so you can test whatever you need to test.
I'm not sure I've fully understood your question, but assuming a few things the following might work. First assumption is that your Client class has a flag alive in it indicating if it is alive or dead.
while(clients.size()>0){
client = clients.remove();
if (client.isAlive()) {
Socket socket= server.accept();
socket.close();
}
}
It looks like a need for synchronisation on clients so that the size of clients is changed at known points.
How about an extra thread to stop the serversocket when all clients are gone? :) Something like
new Thread() {
public void run() {
if (clients.isEmpty()) {
try { server.close();} catch (IOException e){...}
}
}
}.start();
while(clients.size()>0){
if (!clients.isEmpty()) {
Socket socket= server.accept();
socket.close();
}
}
精彩评论