forked from leuchter/VS_LET
116 lines
3.4 KiB
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();
|
|
}
|
|
}
|