forked from leuchter/VS_LET
1
0
Fork 0
VS/03-tcp/tcp.echo_solution/src/main/java/vs/EchoServerThreadPool.java

116 lines
3.4 KiB
Java

package vs;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* threaded server for var.sockets.tcp.echo Echo service. waits for the next
* client to connect, creates thread and handles connection in concurrently:
* sends greeting message to client, reads line by line from client and sends it
* back adding "echo: " in front of each line until connection is closed by
* client.
*
* @author Sandro Leuchter
*
*/
public class EchoServerThreadPool {
/**
* port on which this service is currently listening on localhost
*/
private final int port;
/**
* thread pool of this server
*/
private final Executor threadPool;
/**
* the only constructor for this class
*
* @param port port on which this service will be listening on localhost
*/
public EchoServerThreadPool(int port) {
this.port = port;
// threadPool = Executors.newSingleThreadExecutor();
// threadPool = Executors.newCachedThreadPool();
this.threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
}
/**
* creates server socket on localhost:port, infinitely handles connections to
* clients concurrently
*/
public void start() {
try (ServerSocket serverSocket = new ServerSocket(this.port)) {
System.out.println("EchoServer (threaded) auf " + serverSocket.getLocalSocketAddress() + " gestartet ...");
while (true) {
Socket socket = serverSocket.accept();
this.threadPool.execute(new EchoThread(socket));
}
} catch (IOException e) {
System.err.println(e);
}
}
/**
* Each connection is handled with an instance of this class.
*/
private class EchoThread implements Runnable {
/**
* TCP connection to client
*/
private final Socket socket;
/**
* the only constructor for this class
*
* @param socket the individual socket that the server created on accepting a
* client that this EchoThread instance will be communicating with
*/
public EchoThread(Socket socket) {
this.socket = socket;
}
/**
* defines the behavior of this Thread instance, will be executed concurrently
* if start() is called on instance
*
*/
@Override
public void run() {
SocketAddress socketAddress = this.socket.getRemoteSocketAddress();
System.out.println("Verbindung zu " + socketAddress + " aufgebaut");
try (BufferedReader in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
PrintWriter out = new PrintWriter(this.socket.getOutputStream(), true)) {
out.println("Server ist bereit ...");
String input;
while ((input = in.readLine()) != null) {
System.out.println(socketAddress + ">> [" + input + "]");
out.println("echo: " + input);
}
} catch (Exception e) {
System.err.println(e);
} finally {
System.out.println("Verbindung zu " + socketAddress + " abgebaut");
}
}
}
/**
* main method: entrypoint to run service
*
* @param args args[0] must be the port number of the server (int); rest of args
* is ignored
*/
public static void main(String[] args) {
int port = Integer.parseInt(args[0]);
new EchoServerThreadPool(port).start();
}
}