![]() |
![]() Fall Semester 2002 |
This serves as a quick introduction to Java.
For more introductory information about programming in Java please check A201 lecture notes.
We therefore start by testing our basic tools.
All of our programs will be presented in this way.frilled.cs.indiana.edu%emacs HelloWorld.java frilled.cs.indiana.edu%ls -ld HelloWorld.java -rw------- 1 dgerman 122 Jan 6 19:18 HelloWorld.java frilled.cs.indiana.edu%cat HelloWorld.java class HelloWorld { public static void main(String[] args) { System.out.println("To infinity, and beyond!"); } } frilled.cs.indiana.edu%javac HelloWorld.java frilled.cs.indiana.edu%ls -l * -rw------- 1 dgerman 438 Jan 6 19:23 HelloWorld.class -rw------- 1 dgerman 122 Jan 6 19:18 HelloWorld.java frilled.cs.indiana.edu%java HelloWorld To infinity, and beyond! frilled.cs.indiana.edu%
Ocasionally, we will have
EXERCISES
HelloWorld
as above.
HelloWorld
and see what errors
you get.
The next program demonstrates
The program declares and uses local variables.frilled.cs.indiana.edu%cat Fibonacci.java class Fibonacci { public static void main(String[] args) { int low = 1, high = 1; System.out.println(low); while (high < 50) { System.out.println(high); high = low + high; // new high low = high - low; /* new low is (sum - old low) that is, the old high */ } } } frilled.cs.indiana.edu%javac Fibonacci.java frilled.cs.indiana.edu%java Fibonacci 1 1 2 3 5 8 13 21 34 frilled.cs.indiana.edu%
Variables have types.
In Java we have the following types:
boolean
char
byte
short
int
long
float
double
Local variables need to be initialized by the programmer.
Let us remind ourselves that a method is composed of:
println
method is overloaded
as it accepts arguments of different types. EXERCISES
12
17.9
, and
"Strings like this."
Take a look at the following changes:
You can group related constants within a class.frilled.cs.indiana.edu%cat Fibonacci2.java class Fibonacci2 { static final int MAX = 50; /** Print the Fibonacci sequence for values < MAX */ public static void main(String[] args) { int low = 1; int high = 1; System.out.println(low); while (high < MAX) { System.out.println(high); high = low + high; // new high low = high - low; /* new low is (sum - old low) that is, the old high */ } } } frilled.cs.indiana.edu%
Note that you can compile, but not run, thefrilled.cs.indiana.edu%ls -l total 4 -rw------- 1 dgerman 303 Jan 6 19:41 Fibonacci.java -rw------- 1 dgerman 407 Jan 6 20:18 Fibonacci2.java -rw------- 1 dgerman 122 Jan 6 19:18 HelloWorld.java -rw------- 1 dgerman 163 Jan 6 20:22 Suit.java frilled.cs.indiana.edu%cat Suit.java class Suit { final static int CLUBS = 1 ; final static int DIAMONDS = 2 ; final static int HEARTS = 3 ; final static int SPADES = 4 ; } frilled.cs.indiana.edu%javac Suit.java frilled.cs.indiana.edu%ls -ld *.class -rw------- 1 dgerman 308 Jan 6 20:22 Suit.class frilled.cs.indiana.edu%
Suit
class. EXERCISES
HelloWorld
application to use a named
string constant as the string to print.
PI
defined in class Math
.
while
loop could be replaced by an equivalent
for
loop, as follows:
As a side note, there is a closed formula for the Fibonacci numbers:frilled.cs.indiana.eduls -l total 5 -rw------- 1 dgerman 303 Jan 6 19:41 Fibonacci.java -rw------- 1 dgerman 407 Jan 6 20:18 Fibonacci2.java -rw------- 1 dgerman 122 Jan 6 19:18 HelloWorld.java -rw------- 1 dgerman 491 Jan 6 21:15 ImprovedFibonacci.java -rw------- 1 dgerman 163 Jan 6 20:22 Suit.java frilled.cs.indiana.educat ImprovedFibonacci.java class ImprovedFibonacci { /** Print out the first few Fibonacci * numbers, marking evens with a '*' */ static final int MAX_INDEX = 9; public static void main(String[] args) { int low = 1; int high = 1; String mark; System.out.println("1: " + low); for (int i = 2; i < MAX_INDEX; i++) { if (high % 2 == 0) mark = " *"; else mark = ""; System.out.println(i + ": " + high + mark); high += low; low = high - low; } } } frilled.cs.indiana.edujavac ImprovedFibonacci.java frilled.cs.indiana.eduls -ld *.class -rw------- 1 dgerman 819 Jan 6 21:17 ImprovedFibonacci.class frilled.cs.indiana.edujava ImprovedFibonacci 1: 1 2: 1 3: 2 * 4: 3 5: 5 6: 8 * 7: 13 8: 21 frilled.cs.indiana.edu
EXERCISESfrilled.cs.indiana.edu%cat One.java class One { public static void main(String[] args) { double a = (1 + Math.sqrt(5)) / 2; double b = (1 - Math.sqrt(5)) / 2; for (int i = 1; i < 9; i++) { System.out.print(i + ": "); System.out.println (Math.round ((Math.pow(a, i) - Math.pow(b,i)) / Math.sqrt(5))); } } } frilled.cs.indiana.edu%java One 1: 1 2: 1 3: 2 4: 3 5: 5 6: 8 7: 13 8: 21 frilled.cs.indiana.edu%
i
counts backward
instead of forward (use closed formula)
Here's a neat example of a class (class Point { public double x, y; } class Two { public static void main(String[] args) { Point lowerLeft = new Point(); Point upperRight = new Point(); Point middlePoint = new Point(); lowerLeft.x = 0.0; lowerLeft.y = 0.0; upperRight.x = 1280.0; upperRight.y = 1024.0; middlePoint.x = 640.0; middlePoint.y = 512.0; } }
static
) variable:
Let's add some methods to this class now.class Point { public double x, y; public static Point origin = new Point(); }
Let's see this program running:class Point { public double x, y; public static Point origin = new Point(); public void clear() { x = 0; y = 0; } public double distanceTo(Point that) { double xdiff = x - that.x; double ydiff = y - that.y; return Math.sqrt(xdiff * xdiff + ydiff * ydiff); } public void moveBy(double dx, double dy) { x += dx; y += dy; } public void moveTo(double x, double y) { this.x = x; this.y = y; } public String toString() { return "(" + this.x + ", " + this.y + ")"; } Point (double a, double b) { this.x = a; this.y = b; } Point() { } public static void main(String[] args) { Point a = new Point(1, 0); System.out.println("Point a has been created: " + a.toString()); Point b = new Point(6, 6); System.out.println("Point b has been created: " + b); System.out.println ("Distance from " + a + " to " + b + " is " + a.distanceTo(b)); System.out.println ("Distance from " + b + " to " + a + " is " + b.distanceTo(a)); a.moveTo(0, 4); System.out.println("Here's a after being moved to (0, 4): " + a); b.moveBy(-2, 1); System.out.println("Here's b after being moved by (-2, 1): " + b); System.out.println ("The distance between " + a + " and " + b + " is " + "now " + a.distanceTo(b) + " == " + b.distanceTo(a)); System.out.println ("The distance from " + a + " to origin " + Point.origin + " is " + a.distanceTo(Point.origin) + " (easy to check)."); System.out.println ("The distance from " + b + " to origin " + Point.origin + " is " + b.distanceTo(Point.origin) + "."); } }
We've thus seen:frilled.cs.indiana.edu%java Point Point a has been created: (1.0, 0.0) Point b has been created: (6.0, 6.0) Distance from (1.0, 0.0) to (6.0, 6.0) is 7.810249675906654 Distance from (6.0, 6.0) to (1.0, 0.0) is 7.810249675906654 Here's a after being moved to (0, 4): (0.0, 4.0) Here's b after being moved by (-2, 1): (4.0, 7.0) The distance between (0.0, 4.0) and (4.0, 7.0) is now 5.0 == 5.0 The distance from (0.0, 4.0) to origin (0.0, 0.0) is 4.0 (easy to check). The distance from (4.0, 7.0) to origin (0.0, 0.0) is 8.06225774829855. frilled.cs.indiana.edu%
Point
which sets the current object's
coordinates to those of a passed in Point
object. Call this new
method moveTo
, and use it in a few examples.
clone()
method to the Point
class,
that returns a copy of the Point
it is invoked on.
Calculator
class.
EXERCISESfrilled.cs.indiana.edu%cat Calculator.java class Calculator { int add(int n, int m) { if (m == 0) return n; else return add(n+1, m-1); } public static void main(String[] args) { Calculator a = new Calculator(); System.out.println(" 1 + 2 = " + a.add( 1, 2)); System.out.println(" 4 + 1 = " + a.add( 4, 1)); System.out.println("-1 + 2 = " + a.add(-1, 2)); } } frilled.cs.indiana.edu%javac Calculator.java frilled.cs.indiana.edu%java Calculator 1 + 2 = 3 4 + 1 = 5 -1 + 2 = 1 frilled.cs.indiana.edu%
int fibonacci(int n)
to
all Calculator
s.
add
method so it also works for
negative values int its second argument.
Here's an implementation of this game.frilled.cs.indiana.edu%java Game Welcome to the Game. Here's your hand: 48 51 52 15 19 = 185 Here's the computer's: 29 31 41 44 40 = 185 This game is tied: 185 - 185 frilled.cs.indiana.edu%java Game Welcome to the Game. Here's your hand: 5 19 52 52 40 = 168 Here's the computer's: 39 19 39 1 44 = 142 You win this time by 26 point(s). frilled.cs.indiana.edu%java Game Welcome to the Game. Here's your hand: 6 34 19 37 28 = 124 Here's the computer's: 48 9 8 16 33 = 114 You win this time by 10 point(s). frilled.cs.indiana.edu%java Game Welcome to the Game. Here's your hand: 30 39 52 11 23 = 155 Here's the computer's: 19 39 21 8 50 = 137 You win this time by 18 point(s). frilled.cs.indiana.edu%java Game Welcome to the Game. Here's your hand: 27 44 38 48 39 = 196 Here's the computer's: 42 47 38 3 4 = 134 You win this time by 62 point(s). frilled.cs.indiana.edu%java Game Welcome to the Game. Here's your hand: 30 44 35 4 28 = 141 Here's the computer's: 43 2 52 18 26 = 141 This game is tied: 141 - 141 frilled.cs.indiana.edu%java Game Welcome to the Game. Here's your hand: 42 32 52 2 27 = 155 Here's the computer's: 20 35 37 47 19 = 158 Computer wins this time by 3 point(s). frilled.cs.indiana.edu%java Game Welcome to the Game. Here's your hand: 47 5 47 52 48 = 199 Here's the computer's: 45 50 42 36 38 = 211 Computer wins this time by 12 point(s). frilled.cs.indiana.edu%java Game Welcome to the Game. Here's your hand: 4 39 25 46 37 = 151 Here's the computer's: 47 10 42 38 19 = 156 Computer wins this time by 5 point(s). frilled.cs.indiana.edu%java Game Welcome to the Game. Here's your hand: 20 51 29 35 1 = 136 Here's the computer's: 46 49 23 52 21 = 191 Computer wins this time by 55 point(s). frilled.cs.indiana.edu%java Game Welcome to the Game. Here's your hand: 19 8 27 48 20 = 122 Here's the computer's: 16 33 18 46 45 = 158 Computer wins this time by 36 point(s). frilled.cs.indiana.edu%java Game Welcome to the Game. Here's your hand: 24 11 8 44 48 = 135 Here's the computer's: 13 22 46 26 19 = 126 You win this time by 9 point(s). frilled.cs.indiana.edu%
Here's a simpler example involving arrays:class Game { public static void main(String[] args) { System.out.println("Welcome to the Game."); Hand yours = new Hand(); System.out.print("Here's your hand: "); yours.show(); Hand computer = new Hand(); System.out.print("Here's the computer's: "); computer.show(); if (yours.value() > computer.value()) { System.out.println("You win this time by " + (yours.value() - computer.value()) + " point(s)"); } else if (yours.value() < computer.value()) { System.out.println("Computer wins this time by " + (computer.value() - yours.value()) + " point(s)."); } else { System.out.println("This game is tied: " + yours.value() + " - " + computer.value()); } } } class Hand { public static final int HAND_SIZE = 5; int[] cards; Hand() { cards = new int[HAND_SIZE]; for (int i = 0; i < cards.length; i++) { cards[i] = (int)(Math.random() * 52) + 1; } } void show() { for (int i = 0; i < cards.length; i++) { System.out.print(cards[i] + " "); } System.out.println(" = " + this.value()); } int value() { int val = 0; for (int i = 0; i < cards.length; i++) { val += cards[i]; } return val; } }
An array with length zero is an empty array.frilled.cs.indiana.edu%cat Sum.java class Sum { public static void main(String[] args) { int sum = 0; for (int i = 0; i < args.length; i++) { sum += Integer.parseInt(args[i]); } System.out.println(sum); } } frilled.cs.indiana.edu%javac Sum.java frilled.cs.indiana.edu%java Sum 0 frilled.cs.indiana.edu%java Sum -1 2 3 -3 1 frilled.cs.indiana.edu%java Sum 1 2 3 4 10 frilled.cs.indiana.edu%
The empty array is more than no array at all, as shown below:
Exceptions could be thrown (and caught) when something bad happens.frilled.cs.indiana.edu%cat Four.java class Four { public static void main(String[] args) { int[] a = { 1, 2, 3, 4}; int[] b = { }; int[] c = new int[0]; /* int[] d; */ int[] e = null; Four.show("a: ", a); Four.show("b: ", b); Four.show("c: ", c); // Four.show("d: ", d); Four.show("e: ", e); } static void show(String u, int[] v) { if (v == null || v.length == 0) { // order is important System.out.println(u + "Not much to show."); } else { System.out.print(u); for (int i = 0; i < v.length; i++) { System.out.print(v[i] + " "); } System.out.println(); } } } frilled.cs.indiana.edu%javac Four.java frilled.cs.indiana.edu%java Four a: 1 2 3 4 b: Not much to show. c: Not much to show. e: Not much to show. frilled.cs.indiana.edu%
frilled.cs.indiana.edu%cat Add.java class Add { public static void main(String[] args) { int sum = 0; try { sum = Integer.parseInt(args[0]) + Integer.parseInt(args[1]); System.out.println("The sum is: " + sum); } catch (Exception e) { System.out.println("Exception caught (by us): " + e); System.out.println("Can't calculate sum, arguments missing."); } finally { System.out.println("Thanks for using this program."); } } } frilled.cs.indiana.edu%javac Add.java frilled.cs.indiana.edu%java Add 1 2 The sum is: 3 Thanks for using this program. frilled.cs.indiana.edu%java Add 2 1 The sum is: 3 Thanks for using this program. frilled.cs.indiana.edu%java Add -1 -2 The sum is: -3 Thanks for using this program. frilled.cs.indiana.edu%java Add -1 7 2 3 The sum is: 6 Thanks for using this program. frilled.cs.indiana.edu%java Add 1 Exception caught (by us): java.lang.ArrayIndexOutOfBoundsException Can't calculate sum, arguments missing. Thanks for using this program. frilled.cs.indiana.edu%java Add Exception caught (by us): java.lang.ArrayIndexOutOfBoundsException Can't calculate sum, arguments missing. Thanks for using this program. frilled.cs.indiana.edu%
String
s are almost arrays of char
s, but not quite.
EXERCISESfrilled.cs.indiana.edu%cat Five.java class Five { public static void main(String[] args) { String in = args[0]; char[] a = new char[in.length()]; for (int i = 0; i < args[0].length(); i++) { a[i] = in.charAt(i); } for (int i = 0; i < a.length; i++) { System.out.print("(" + a[i] + ")"); } System.out.println(); } } frilled.cs.indiana.edu%javac Five.java frilled.cs.indiana.edu%java Five Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException at Five.main(Five.java:4) frilled.cs.indiana.edu%java Five java (j)(a)(v)(a) frilled.cs.indiana.edu%java Five "I see..." (I)( )(s)(e)(e)(.)(.)(.) frilled.cs.indiana.edu%java Five wonderful (w)(o)(n)(d)(e)(r)(f)(u)(l) frilled.cs.indiana.edu%
Second, here's a starting point.frilled.cs.indiana.edu%java Fifteen 0920 1025 1 hour(s) 5 minutes frilled.cs.indiana.edu%java Fifteen 1025 0920 22 hour(s) 55 minutes frilled.cs.indiana.edu%
Here's a simple example of inheritance or class extension.frilled.cs.indiana.edu%cat Fifteen.java class Fifteen { public static void main(String[] args) { String one = args[0], two = args[1]; String h1 = one.substring(0, 2), m1 = one.substring(2, 4), h2 = two.substring(0, 2), m2 = two.substring(2); System.out.println("First time: " + h1 + " hours, and " + m1 + " minutes."); System.out.println("Second time: " + h2 + " hours, and " + m2 + " minutes."); } } frilled.cs.indiana.edu%javac Fifteen.java frilled.cs.indiana.edu%java Fifteen Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException at Fifteen.main(Fifteen.java:4) frilled.cs.indiana.edu%java Fifteen 0920 1000 First time: 09 hours, and 20 minutes. Second time: 10 hours, and 00 minutes. frilled.cs.indiana.edu%java Fifteen 1000 0945 First time: 10 hours, and 00 minutes. Second time: 09 hours, and 45 minutes. frilled.cs.indiana.edu%
Here's a different, somewhat similar, example on interfaces.frilled.cs.indiana.edu%cat Stages.java class One { int add(int n, int m) { if (m == 0) return n; else return add(n+1, m-1); } } class Two extends One { int mul(int n, int m) { if (m == 1) return n; else return add(n, mul(n, m-1)); } } class Three extends Two { int pow(int n, int m) { if (m == 0) return 1; else return mul(n, pow(n, m-1)); } } class Calculator { public static void main(String[] args) { Three calc = new Three(); int n = 3, m = 5; System.out.println(n + " + " + m + " = " + calc.add(n, m)); System.out.println(n + " * " + m + " = " + calc.mul(n, m)); System.out.println(n + " ^ " + m + " = " + calc.pow(n, m)); } } frilled.cs.indiana.edu%javac Stages.java frilled.cs.indiana.edu%java Calculator 3 + 5 = 8 3 * 5 = 15 3 ^ 5 = 243 frilled.cs.indiana.edu%
EXERCISESfrilled.cs.indiana.edu%cat Example.java interface Multiplier { int mul(int n, int m); } class Alpha implements Multiplier { public int mul(int n, int m) { return n * m; } } class Beta implements Multiplier { public int mul(int n, int m) { int result = 0; for (int i = 0; i < m; i++) result += n; return result; } } class Gamma implements Multiplier { public int mul(int n, int m) { if (m == 1) return n; else return n + mul(n, m-1); } } class Example { public static void main(String[] args) { Alpha a = new Alpha(); Beta b = new Beta(); Gamma g = new Gamma(); int n = 5, m = 3; System.out.println(n + " * " + m + " = " + a.mul(n,m) + " (by Alpha)"); System.out.println(n + " * " + m + " = " + b.mul(n,m) + " (by Beta )"); System.out.println(n + " * " + m + " = " + g.mul(n,m) + " (by Gamma)"); } } frilled.cs.indiana.edu%javac Example.java frilled.cs.indiana.edu%java Example 5 * 3 = 15 (by Alpha) 5 * 3 = 15 (by Beta ) 5 * 3 = 15 (by Gamma) frilled.cs.indiana.edu%
The fundamental compilation unit in Java is theclass Weird { public static void main(String[] args) { String one = "Go Hoosiers!"; Object two = "All the way!"; System.out.println(one + " " + two); two = one; System.out.println(one + " " + two); two = "All the way!"; System.out.println(one + " " + two); one = (String)two; System.out.println(one + " " + two); one = "Go Hoosiers!"; System.out.println(one + " " + two); } }
package
.
EXERCISESfrilled.cs.indiana.edu%cat One.java import java.util.Date; class One { public static void main(String[] args) { System.out.println(new Date()); } } frilled.cs.indiana.edu%cat Two.java class Two { public static void main(String[] args) { System.out.println(new java.util.Date()); } } frilled.cs.indiana.edu%cat Three.java import java.util.*; class Three { public static void main(String[] args) { System.out.println(new Date()); } } frilled.cs.indiana.edu%javac One.java Two.java Three.java frilled.cs.indiana.edu%java One; java Two; java Three Mon Mar 25 16:06:25 EST 2002 Mon Mar 25 16:06:26 EST 2002 Mon Mar 25 16:06:26 EST 2002 frilled.cs.indiana.edu%
This is the minimal that we need.class Math { public static void main(String[] args) { System.out.println(Math.max(1, 2)); } }
But, as the lab notes of this week are showing, we need a bit more.
So here's Part Two of these notes (more realistic in indicating how much Java is really required).
We
discuss
First, we are going to write a network client.
/* * Copyright (c) 2000 David Flanagan. All rights reserved. * This code is from the book Java Examples in a Nutshell, 2nd Edition. * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied. * You may study, use, and modify it for any non-commercial purpose. * You may distribute it non-commercially as long as you retain this notice. * For a commercial use license, or to purchase the book (recommended), * visit http://www.davidflanagan.com/javaexamples2. */ import java.io.*; import java.net.*; /** * This program connects to a server at a specified host and port. * It reads text from the console and sends it to the server. * It reads text from the server and sends it to the console. **/ public class GenericClient { public static void main(String[] args) throws IOException { try { // Check the number of arguments if (args.length != 2) throw new IllegalArgumentException("Wrong number of args"); // Parse the host and port specifications String host = args[0]; int port = Integer.parseInt(args[1]); // Connect to the specified host and port Socket s = new Socket(host, port); // Set up streams for reading from and writing to the server. // The from_server stream is final for use in the inner class below final Reader from_server=new InputStreamReader(s.getInputStream()); PrintWriter to_server = new PrintWriter(s.getOutputStream()); // Set up streams for reading from and writing to the console // The to_user stream is final for use in the anonymous class below BufferedReader from_user = new BufferedReader(new InputStreamReader(System.in)); // Pass true for auto-flush on println() final PrintWriter to_user = new PrintWriter(System.out, true); // Tell the user that we've connected to_user.println("Connected to " + s.getInetAddress() + ":" + s.getPort()); // Create a thread that gets output from the server and displays // it to the user. We use a separate thread for this so that we // can receive asynchronous output Thread t = new Thread() { public void run() { char[] buffer = new char[1024]; int chars_read; try { // Read characters until the stream closes while((chars_read = from_server.read(buffer)) != -1) { // Loop through the array of characters, and // print them out, converting all \n characters // to the local platform's line terminator. // This could be more efficient, but it is probably // faster than the network is, which is good enough for(int i = 0; i < chars_read; i++) { if (buffer[i] == '\n') to_user.println(); else to_user.print(buffer[i]); } to_user.flush(); } } catch (IOException e) { to_user.println(e); } // When the server closes the connection, the loop above // will end. Tell the user what happened, and call // System.exit(), causing the main thread to exit along // with this one. to_user.println("Connection closed by server."); System.exit(0); } }; // We set the priority of the server-to-user thread above to be // one level higher than the main thread. We shouldn't have to do // this, but on some operating systems, output sent to the console // doesn't appear when a thread at the same priority level is // blocked waiting for input from the console. t.setPriority(Thread.currentThread().getPriority() + 1); // Now start the server-to-user thread t.start(); // In parallel, read the user's input and pass it on to the server. String line; while((line = from_user.readLine()) != null) { to_server.print(line + "\n"); to_server.flush(); } // If the user types a Ctrl-D (Unix) or Ctrl-Z (Windows) to end // their input, we'll get an EOF, and the loop above will exit. // When this happens, we stop the server-to-user thread and close // the socket. s.close(); to_user.println("Connection closed by client."); System.exit(0); } // If anything goes wrong, print an error message catch (Exception e) { System.err.println(e); System.err.println("Usage: java GenericClient <hostname> <port>"); } } }Let's see how it works:
This is our (own)burrowww.cs.indiana.edu% pwd /nfs/paca/home/user1/dgerman/browser/server burrowww.cs.indiana.edu% ls -ld * -rw-r--r-- 1 dgerman faculty 4749 Aug 6 23:43 GenericClient.java burrowww.cs.indiana.edu% javac GenericClient.java burrowww.cs.indiana.edu% java GenericClient burrowww.cs.indiana.edu 10200 Connected to burrowww.cs.indiana.edu/129.79.245.98:10200 GET /index.html <html> <head><title>Homework One Page</title></head> <body bgcolor=white> <center> <img src="http://www.cs.indiana.edu/images/academics.jpg"> </center> <p> SAMPLE HOMEWORK ONE PAGE: Your first homework assignment is asking you to <ul> <li> install Apache, and to <li> post a picture of yourself on the website, </ul> as I include above. Please also provide links to a couple of other documents that describe your interests, and add more information to your page. (For example my current interests are: <a href="http://www.cs.indiana.edu/classes/a201">A201</a> and <a href="http://www.cs.indiana.edu/classes/a348">A348</a>). Later you will provide links to your homework assignments from this page. <p> </body> </html> Connection closed by server. burrowww.cs.indiana.edu%
telnet
. Now for the server part. We start from this:
Let's see how we can use this.import java.io.*; import java.net.*; public class HTTPServer { public static void main(String[] args) throws Exception { final int httpd = Integer.parseInt(args[0]); // our port ServerSocket ssock = new ServerSocket(httpd); System.out.println("Have opened port " + httpd + " locally."); Socket sock = ssock.accept(); System.out.println("Client has made socket connection."); OneConnection client = new OneConnection(sock); String s = client.getRequest(); } } class OneConnection { Socket sock; BufferedReader in = null; DataOutputStream out = null; OneConnection(Socket sock) throws Exception { this.sock = sock; in = new BufferedReader (new InputStreamReader (sock.getInputStream())); out = new DataOutputStream(sock.getOutputStream()); } String getRequest() throws Exception { String s = null; while ((s = in.readLine()) != null) { System.out.println("got: " + s); } return s; } }
We can start the server on tucotuco
and connect from burrowww
.
By the way:
(Do you remember what that means?)burrowww.cs.indiana.edu% hostlist burrow burrowww bandicoot blesmol bobac degu jerboa marmot molerat prairiedog suslik tucotuco whistlepig woodchuck burrowww.cs.indiana.edu%
Here now is a simultaneous set of screens, first the server side:
And the client side:tucotuco.cs.indiana.edu% javac HTT*.java tucotuco.cs.indiana.edu% java HTTPServer 12345 Have opened port 12345 locally. Client has made socket connection. got: bye got: I am here got: klsjsajdasldkja got: got: got: asdkjasjdaslkd tucotuco.cs.indiana.edu%
So far, so good.burrowww.cs.indiana.edu% java GenericClient tucotuco.cs.indiana.edu 12345 Connected to tucotuco.cs.indiana.edu/129.79.245.110:12345 bye I am here klsjsajdasldkja asdkjasjdaslkd ^Cburrowww.cs.indiana.edu%
We, of course, can also make a connection using a web browser.
Of, course, we don't show the browser.tucotuco.cs.indiana.edu% pwd /nfs/paca/home/user1/dgerman/browser/server tucotuco.cs.indiana.edu% java HTTPServer 12345 Have opened port 12345 locally. Client has made socket connection. got: GET / HTTP/1.0 got: Connection: Keep-Alive got: User-Agent: Mozilla/4.79 [en] (X11; U; SunOS 5.8 sun4u) got: Host: tucotuco.cs.indiana.edu:12345 got: Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */* got: Accept-Encoding: gzip got: Accept-Language: en got: Accept-Charset: iso-8859-1,*,utf-8 got:
But you can try, as well, and in the process see the HTTP headers.
Let's teach our server a little HTTP:
Here's what happens if you start it and call withimport java.io.*; import java.net.*; public class HTTPServer { public static void main(String[] args) throws Exception { final int httpd = Integer.parseInt(args[0]); // our port ServerSocket ssock = new ServerSocket(httpd); System.out.println("Have opened port " + httpd + " locally."); Socket sock = ssock.accept(); System.out.println("Client has made socket connection."); OneConnection_A client = new OneConnection_A(sock); String s = client.getRequest(); } } class OneConnection { Socket sock; BufferedReader in = null; DataOutputStream out = null; OneConnection(Socket sock) throws Exception { this.sock = sock; in = new BufferedReader (new InputStreamReader (sock.getInputStream())); out = new DataOutputStream(sock.getOutputStream()); } String getRequest() throws Exception { String s = null; while ((s = in.readLine()) != null) { System.out.println("got: " + s); } return s; } } class OneConnection_A extends OneConnection { OneConnection_A (Socket sock) throws Exception { super(sock); } String getRequest() throws Exception { String s = null; while ((s = in.readLine()) != null) { System.out.println("got: " + s); if (s.indexOf("GET") > -1) { out.writeBytes("HTTP-1.0 200 OK\r\n"); s = s.substring(4); int i = s.indexOf(" "); System.out.println("file: " + s.substring(0, i)); return s.substring(0, i); } } return null; } }
from Netscape (or some other browser):http://tucotuco.cs.indiana.edu:12345
Now we're getting so much closer:tucotuco.cs.indiana.edu% pwd /nfs/paca/home/user1/dgerman/browser/server tucotuco.cs.indiana.edu% ls -ld * -rw-r--r-- 1 dgerman faculty 4749 Aug 6 23:43 GenericClient.java -rw-r--r-- 1 dgerman faculty 1477 Aug 7 00:36 HTTPServer.java tucotuco.cs.indiana.edu% javac *Server*.java tucotuco.cs.indiana.edu% java HTTPServer 12345 Have opened port 12345 locally. Client has made socket connection. got: GET / HTTP/1.0 file: / tucotuco.cs.indiana.edu%
Assume now you callimport java.io.*; import java.net.*; public class HTTPServer { public static void main(String[] args) throws Exception { final int httpd = Integer.parseInt(args[0]); // our port ServerSocket ssock = new ServerSocket(httpd); System.out.println("Have opened port " + httpd + " locally."); Socket sock = ssock.accept(); System.out.println("Client has made socket connection."); OneConnection_B client = new OneConnection_B(sock); String s = client.getRequest(); client.sendFile(s); } } class OneConnection { Socket sock; BufferedReader in = null; DataOutputStream out = null; OneConnection(Socket sock) throws Exception { this.sock = sock; in = new BufferedReader (new InputStreamReader (sock.getInputStream())); out = new DataOutputStream(sock.getOutputStream()); } String getRequest() throws Exception { String s = null; while ((s = in.readLine()) != null) { System.out.println("got: " + s); } return s; } } class OneConnection_A extends OneConnection { OneConnection_A (Socket sock) throws Exception { super(sock); } String getRequest() throws Exception { String s = null; while ((s = in.readLine()) != null) { System.out.println("got: " + s); if (s.indexOf("GET") > -1) { out.writeBytes("HTTP-1.0 200 OK\r\n"); s = s.substring(4); int i = s.indexOf(" "); System.out.println("file: " + s.substring(0, i)); return s.substring(0, i); } } return null; } } class OneConnection_B extends OneConnection_A { OneConnection_B(Socket sock) throws Exception { super(sock); } void sendFile(String fname) throws Exception { String where = "htdocs" + fname; if (where.indexOf("..") > -1) throw new SecurityException("No access to parent dirs"); System.out.println("Looking for " + where); File f = new File(where); DataInputStream din = new DataInputStream(new FileInputStream(f)); int len = (int) f.length(); byte[] buf = new byte[len]; din.readFully(buf); out.writeBytes("Content-Length: " + len + "\r\n"); out.writeBytes("Content-type: text/html\r\n\r\n"); out.write(buf); out.flush(); out.close(); } }
using Netscape. Then the result is as follows.http://tucotuco.cs.indiana.edu:12345/one.html
First, the server reports all:
Then, the file is shown in the browser.tucotuco.cs.indiana.edu% javac HTTPServer.java tucotuco.cs.indiana.edu% du -a htdocs 1 htdocs/one.html 2 htdocs tucotuco.cs.indiana.edu% cat htdocs/one.html This is a very simple file, really... :-) tucotuco.cs.indiana.edu% java HTTPServer 12345 Have opened port 12345 locally. Client has made socket connection. got: GET /one.html HTTP/1.0 file: /one.html Looking for htdocs/one.html tucotuco.cs.indiana.edu%
(One can also verify that with our GenericClient
).
Last improvement we need to make: turn the server in a multithreaded server.
This way it can receive and service more than one call.import java.io.*; import java.net.*; public class HTTPServer { public static void main(String[] args) throws Exception { final int httpd = Integer.parseInt(args[0]); // our port ServerSocket ssock = new ServerSocket(httpd); while (true) { Socket sock = ssock.accept(); System.out.println("** Client has made socket connection."); OneConnection_C client = new OneConnection_C(sock); new Thread(client).start(); } } } class OneConnection { Socket sock; BufferedReader in = null; DataOutputStream out = null; OneConnection(Socket sock) throws Exception { this.sock = sock; in = new BufferedReader (new InputStreamReader (sock.getInputStream())); out = new DataOutputStream(sock.getOutputStream()); } String getRequest() throws Exception { String s = null; while ((s = in.readLine()) != null) { System.out.println("got: " + s); } return s; } } class OneConnection_A extends OneConnection { OneConnection_A (Socket sock) throws Exception { super(sock); } String getRequest() throws Exception { String s = null; while ((s = in.readLine()) != null) { System.out.println("got: " + s); if (s.indexOf("GET") > -1) { out.writeBytes("HTTP-1.0 200 OK\r\n"); s = s.substring(4); int i = s.indexOf(" "); System.out.println("file: " + s.substring(0, i)); return s.substring(0, i); } } return null; } } class OneConnection_B extends OneConnection_A { OneConnection_B(Socket sock) throws Exception { super(sock); } void sendFile(String fname) throws Exception { String where = "htdocs" + fname; if (where.indexOf("..") > -1) throw new SecurityException("No access to parent dirs"); System.out.println("Looking for " + where); File f = new File(where); DataInputStream din = new DataInputStream(new FileInputStream(f)); int len = (int) f.length(); byte[] buf = new byte[len]; din.readFully(buf); out.writeBytes("Content-Length: " + len + "\r\n"); out.writeBytes("Content-type: text/html\r\n\r\n"); out.write(buf); out.flush(); out.close(); } } class OneConnection_C extends OneConnection_B implements Runnable { OneConnection_C(Socket sock) throws Exception { super(sock); } public void run() { try { String filename = getRequest(); sendFile(filename); } catch (Exception e) { System.out.println("Exception: " + e); } } }
The output above was generated by calling the server three times:tucotuco.cs.indiana.edu% java HTTPServer 12345 ** Client has made socket connection. got: GET /one.html HTTP/1.0 file: /one.html Looking for htdocs/one.html ** Client has made socket connection. got: GET /two.html HTTP/1.0 file: /two.html Looking for htdocs/two.html Exception: java.io.FileNotFoundException: htdocs/two.html (No such file or directory) ** Client has made socket connection. got: GET /one.html HTTP/1.0 file: /one.html Looking for htdocs/one.html ^Ctucotuco.cs.indiana.edu%
One of the files is missing, hence the exception.http://tucotuco.cs.indiana.edu:12345/one.html http://tucotuco.cs.indiana.edu:12345/two.html http://tucotuco.cs.indiana.edu:12345/one.html
I have two more references for I/O and networking.
They're here:
http://www.cs.indiana.edu/classes/a348/CTED/moduleFour/lectures/Apr22.html
)
http://www.cs.indiana.edu/classes/a348/CTED/moduleFour/lectures/Apr17.html
)
And here's a very basic reference to
http://www.cs.indiana.edu/classes/a348/CTED/moduleFour/lectures/Apr10.html
)