I need to make a client queue with ThreadPoolExecutor and an ability to drop clients if it exceeds some number (5 for example). It is kinda DDOS protection. When client #6 is requesting my server - it got dropped, etc. I got my server and client code, but I don't know how to realize ThreadPoolExecutor and DiscardPolicy. Ideas or examples?
Simple server:
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
ServerSocket server = new ServerSocket (3000);
ExecutorService es = Executors.newFixedThreadPool(2);
Semaphore semaphore = new Semaphore (2);
while(true){
semaphore.acquire();
Socket accept2 = server.accept();
es.execute(()->{
try (Socket accept = accept2) {
serve(accept);
} catch (Exception exception) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, exception);
}
finally {
semaphore.release();
}
});
}
}
private static void serve(final Socket accept) throws ClassNotFoundException, IOException {
InputStream inputStream = accept.getInputStream();
OutputStream outputStream = accept.getOutputStream();
ObjectInputStream inputStream2 = new ObjectInputStream (inputStream);
while (true){
Object readObject = inputStream2.readObject();
System.out.println(readObject);
}
}
}
And a simple client:
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException, InterruptedException {
Socket socket = new Socket ("localhost", 3000);
ObjectOutputStream oos = new ObjectOutputStream (
socket.getOutputStream());
oos.writeObject("First!");
Thread.sleep(10000);
oos.writeObject("First again!");
Thread.sleep(10000);
oos.writeObject("First again again!");
}
}
Use ThreadPoolExecutor
with DiscardPolicy
as below:
int poolSize=1;
int maxPoolSize=2;
int queueSize=5;
long aliveTive=1000;
ArrayBlockingQueue<Runnable> queue= new ArrayBlockingQueue<Runnable>(queueSize);
ThreadPoolExecutor executor= new ThreadPoolExecutor(poolSize,maxPoolSize,aliveTive,
TimeUnit.MILLISECONDS,queue,new ThreadPoolExecutor.DiscardPolicy());
}
Rejected tasks:
New tasks submitted in method execute(Runnable) will be rejected when the Executor has been shut down, and also when the Executor uses finite bounds for both maximum threads and work queue capacity, and is saturated.
In either case, the execute method invokes the RejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor)
method of its RejectedExecutionHandler
.
Four predefined handler policies are provided:
1.ThreadPoolExecutor.AbortPolicy 2.ThreadPoolExecutor.CallerRunsPolicy 3.ThreadPoolExecutor.DiscardPolicy 4.ThreadPoolExecutor.DiscardOldestPolicy
Have a look at this documentation page for more details
If above four does not serve your purpose, you can write custom RejectionHandler by extending RejectedExecutionHandler
.
I have used custom handler when I need to know which task is getting rejected and persist these failures either in disk or database.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With