001package var.sockets.tcp.filer; 002 003import java.io.BufferedReader; 004import java.io.File; 005import java.io.FileReader; 006import java.io.IOException; 007import java.io.PrintWriter; 008import java.net.ServerSocket; 009import java.net.Socket; 010import java.net.SocketAddress; 011import java.util.concurrent.Executor; 012import java.util.concurrent.Executors; 013 014/** 015 * threaded server for var.sockets.tcp.filer File service. waits for clients to 016 * connect. Upon connection sends concurrently to other client connections a 017 * manually defined file back to client. closes the connection directly 018 * afterwards. 019 * 020 * @author Sandro Leuchter 021 * 022 */ 023public class FileServerThreadPool { 024 /** 025 * path to file which will be sent to clients; relative to current working 026 * directory (e.g. project root) 027 */ 028 private static final String FILE = "bin/var/sockets/tcp/filer/message.txt"; 029 /** 030 * port on which this service is currently listening on localhost 031 */ 032 private final int port; 033 /** 034 * thread pool of this server 035 */ 036 private final Executor threadPool; 037 038 /** 039 * the only constructor for this class 040 * 041 * @param port port on which this service will be listening on localhost 042 */ 043 public FileServerThreadPool(int port) { 044 this.port = port; 045 this.threadPool = Executors.newSingleThreadExecutor(); 046 // threadPool = Executors.newCachedThreadPool(); 047 // threadPool = 048 // Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*2); 049 } 050 051 /** 052 * creates server socket on localhost:port, infinitely handles connections to 053 * clients concurrently 054 */ 055 public void start() { 056 try (ServerSocket serverSocket = new ServerSocket(this.port)) { 057 System.out.println("FileServer (threaded) auf " + serverSocket.getLocalSocketAddress() + " gestartet ..."); 058 File file = new File(FILE); 059 if (file.exists()) { 060 System.out.println("\"" + file.getAbsolutePath() + "\" soll gesendet werden."); 061 while (true) { 062 Socket socket = serverSocket.accept(); 063 this.threadPool.execute(new FileThread(socket)); 064 } 065 } 066 } catch (IOException e) { 067 System.err.println(e); 068 } 069 } 070 071 /** 072 * Each connection is handled with an instance of this class. 073 */ 074 private class FileThread implements Runnable { 075 /** 076 * TCP connection to client 077 */ 078 private final Socket socket; 079 080 /** 081 * the only constructor for this class 082 * 083 * @param socket the individual socket that the server created on accepting a 084 * client that this EchoThread instance will be communicating with 085 */ 086 public FileThread(Socket socket) { 087 this.socket = socket; 088 } 089 090 /** 091 * defines the behavior of this Thread instance, will be executed concurrently 092 * if start() is called on instance 093 * 094 */ 095 @Override 096 public void run() { 097 SocketAddress socketAddress = null; 098 try (BufferedReader in = new BufferedReader(new FileReader(FILE)); 099 PrintWriter out = new PrintWriter(this.socket.getOutputStream(), true)) { 100 socketAddress = this.socket.getRemoteSocketAddress(); 101 System.out.println("Verbindung zu " + socketAddress + " aufgebaut"); 102 // Inhalt von in zeilenweise an out senden: 103 System.out.println("Übertragung zu " + socketAddress + " begonnen"); 104 String input; 105 while ((input = in.readLine()) != null) { 106 out.println(input); 107 // Thread.sleep(1000); 108 } 109 System.out.println("Übertragung zu " + socketAddress + " beendet"); 110 } catch (Exception e) { 111 System.err.println(e); 112 } finally { 113 System.out.println("Verbindung zu " + socketAddress + " abgebaut"); 114 } 115 } 116 } 117 118 /** 119 * main method: entrypoint to run service 120 * 121 * @param args args[0] must be the port number of the server (int); rest of args 122 * is ignored 123 */ 124 public static void main(String[] args) { 125 int port = Integer.parseInt(args[0]); 126 new FileServerThreadPool(port).start(); 127 } 128}