// Exam 4 Question 1 for CMSC 838P // Charles B. Cranston xxx-yy-zzz // April 28, 1997 import java.io.*; import java.net.*; public class hserve extends Thread { public static final int DEFAULT_PORT = 1069; public static final int BUFF_SIZE = 4096; Socket sock; // New instantiation of hserve object on every client connect attempt public hserve(Socket s) { sock = s; // Save client socket this.start(); // Start up our thread } // This thread runs on every client connection attempt public void run() { try { StreamTokenizer st = new StreamTokenizer( new InputStreamReader(sock.getInputStream())); st.resetSyntax(); st.whitespaceChars(0,32); st.wordChars(33,255); if ( (StreamTokenizer.TT_WORD!=st.nextToken()) || !("GET".equals(st.sval)) ) throw new IllegalArgumentException("Expected GET"); if ( (StreamTokenizer.TT_WORD!=st.nextToken()) || !st.sval.startsWith("/") ) throw new IllegalArgumentException("Expected /filename"); String filename = st.sval.substring(1); FileInputStream fis = new FileInputStream(filename); System.err.println("Delivering " + filename); OutputStream os = sock.getOutputStream(); // Note: we do our own buffering here. byte buffer[] = new byte[BUFF_SIZE]; int num; while ( -1 != (num=fis.read(buffer)) ) os.write(buffer,0,num); fis.close(); sock.close(); System.err.println("Exit"); } catch (Exception e) { die("Exception in server execution:",e); } } // Utility public static void die(String why, Exception e) { System.err.println(why); System.err.println(e); System.exit(1); } // Main routine. Note this is static and creates a new instantiation // of the hserve object EACH time a client makes a connection. public static void main(String[] args) { try { int port; if ( 0 < args.length ) port = Integer.parseInt(args[0]); else port = DEFAULT_PORT; ServerSocket ss = new ServerSocket(port); System.err.println("Listening on port " + port + "..."); while (true) new hserve( ss.accept() ); // Make thread } catch (Exception e) { die("Exception in server setup:",e); } } }