http..//120.25.121.42.77.14777

Objects and Java Seminar: Network Programming
Sponsored Link &
Objects and Java Seminar by Bill Venners
Network Programming
Lecture Handout
Introduce network programming, IP, and sockets
Give a client/server code example
Compare TCP and UDP
Introduce datagrams and give a code example
Touch on multicast protocol
Introduce URLs and give a code example
Network Programming
Java's architecture is network-oriented.
The java.net library simplifies network programming.&
You use Java I/O streams to communicate via sockets.&
Java's built-in support for multi-threading simplifies creating server
programs that must handle multiple client requests concurrently.
IP and Sockets
IP (internet protocol) breaks communication into packets.&
Packets routed and delivered separately
No delivery guarantee
Max packet size: 65535 (less a 20 byte header)
Sockets enable two machines to communicate via IP.
Other protocols layered on top of IP:&
TCP (Transmission Control Protocol)
UDP (User Datagram Protocol)
IP Addresses
IP requires that each machine have a unique IP address.&
Represented by the InetAddress class of java.net.
IP Addresses are 32-bit numbers, often represented in these two forms:
host name (A DNS name such as <)
quad form (205.73.4.217)
InetAddress.getByName(String) does DNS lookup (or reverse
lookup) and returns an InetAddress object.
Client/Server Computing
A socket connects a client and a server.
The server listens on a port for client requests.
Clients must specify the server's host IP Address and port number to make the
Once connected, the client/server distinction goes away from the
sockets' perspective.
Port Number
Port numbers are 16-bit unsigned integers (represented in Java by
Each port represents a "service" offered by the host.
Ports 0 - 1024 are reserved for well-known services.
You should use parts above 1024 for your own servers.
Clients must specify both port and IP Address when making a connection
The reserved host name "localhost" allows you to test a
network program without a network.
Server and clients can all exist on the same computer.
Three ways to get an InetAddress object for localhost:
InetAddress.getByName(null);
InetAddress.getByName("localhost");
InetAddress.getByName("127.0.0.1");
The Summer Server Application
1 // In file network/ex1/SummerServer.java
2 import java.net.*;
3 import java.io.*;
4 import java.util.StringT
6 public class SummerServer {
public static final int PORT = 2000;
private static class InvalidLongException
extends Exception {
InvalidLongException(String s) {
public String getMessage() {
public static void main(String[] args)
throws IOException {
ServerSocket listener =
new ServerSocket(PORT);
for (;;) {
Socket sock = listener.accept();
serveClient(sock);
sock.close();
listener.close();
private static void serveClient(Socket sock)
throws IOException {
BufferedReader reader = new BufferedReader(
new InputStreamReader(
sock.getInputStream()));
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(
sock.getOutputStream()));
for (;;) {
String s = reader.readLine();
if (s == null) {
String outS
outString =
Long.toString(sumString(s));
catch(InvalidLongException e) {
outString = e.getMessage();
writer.write(outString);
writer.newLine();
writer.flush();
private static long sumString(String s)
throws InvalidLongException {
long sum = 0;
StringTokenizer st = new StringTokenizer(s);
while (st.hasMoreTokens()) {
token = st.nextToken();
sum += Long.parseLong(token);
catch (NumberFormatException e) {
throw new InvalidLongException(
"Invalid number: " + token);
1 // In file network/ex1/SummerClient.java
2 import java.net.*;
3 import java.io.*;
5 public class SummerClient {
public static void main(String[] args)
throws IOException {
InetAddress ia = InetAddress.getByName(null);
Socket sock = new Socket(ia, SummerServer.PORT);
BufferedReader serverReader =
new BufferedReader(
new InputStreamReader(
sock.getInputStream()));
BufferedWriter serverWriter =
new BufferedWriter(
new OutputStreamWriter(
sock.getOutputStream()));
LineNumberReader stdinReader =
new LineNumberReader(
new BufferedReader(
new InputStreamReader(
System.in)));
for (;;) {
String userLine = stdinReader.readLine();
if (userLine == null ||
userLine.length() == 0) {
serverWriter.write(userLine);
serverWriter.newLine();
serverWriter.flush();
String serverLine = serverReader.readLine();
System.out.println(serverLine);
sock.close();
Handling Multiple Clients Concurrently
1 // In file network/ex2/SummerServer.java
2 import java.net.*;
3 import java.io.*;
4 import java.util.StringT
6 public class SummerServer {
public static final int PORT = 2000;
private static class InvalidLongException
extends Exception {
InvalidLongException(String s) {
public String getMessage() {
private static class SummerService
extends Thread {
public SummerService(Socket sock) {
this.sock =
public void run() {
BufferedReader reader =
new BufferedReader(
new InputStreamReader(
sock.getInputStream()));
BufferedWriter writer =
new BufferedWriter(
new OutputStreamWriter(
sock.getOutputStream()));
for (;;) {
String s = reader.readLine();
if (s == null) {
String outS
outString =
Long.toString(sumString(s));
catch(InvalidLongException e) {
outString = e.getMessage();
writer.write(outString);
writer.newLine();
writer.flush();
catch (IOException e) {
sock.close();
catch (IOException e) {
public static void main(String[] args)
throws IOException {
ServerSocket listener = new ServerSocket(PORT);
for (;;) {
Socket sock = listener.accept();
SummerService ss =
new SummerService(sock);
ss.start();
listener.close();
private static long sumString(String s)
throws InvalidLongException {
long sum = 0;
StringTokenizer st = new StringTokenizer(s);
while (st.hasMoreTokens()) {
token = st.nextToken();
sum += Long.parseLong(token);
catch (NumberFormatException e) {
throw new InvalidLongException(
"Invalid number: " + token);
1 // In file network/ex2/SummerClient.java
2 import java.net.*;
3 import java.io.*;
5 public class SummerClient {
public static void main(String[] args)
throws IOException {
InetAddress ia = InetAddress.getByName(null);
Socket sock = new Socket(ia,
SummerServer.PORT);
BufferedReader serverReader =
new BufferedReader(
new InputStreamReader(
sock.getInputStream()));
BufferedWriter serverWriter =
new BufferedWriter(
new OutputStreamWriter(
sock.getOutputStream()));
LineNumberReader stdinReader =
new LineNumberReader(
new BufferedReader(
new InputStreamReader(
System.in)));
for (;;) {
String userLine =
stdinReader.readLine();
if (userLine == null ||
userLine.length() == 0) {
serverWriter.write(userLine);
serverWriter.newLine();
serverWriter.flush();
String serverLine =
serverReader.readLine();
System.out.println(serverLine);
sock.close();
TCP versus UDP
The Summer Server examples use TCP.
TCP (Transmission Control Protocol):
"reliable" (the packets are guaranteed to get there)
packets arrive in the order they were sent
slower than UDP (reliability has overhead)
UDP (User Data Protocol):
"unreliable" (the packets aren't guaranteed to get there)
packets may arrive out of order
packets may arrive faster than they can be consumed
faster than TCP (because less overhead)
Datagrams (UDP packets) are like letters:
You put the recipient's and your own return address (IP Address & Port Number) on the envelope.
You send it, but don't know if whether it will actually get there.
If you send a second letter tomorrow, that might get there first.
UDP is used for:
Clock tickers, game player position announcers, etc...
Streaming protocals such as RealAudio
Designing a faster reliable protocol than TCP
Using Datagrams
Need a DatagramSocket on both client and server.
To send, place the data (up to 65535 bytes less 20-byte header) into
a DatagramPacket.
On receiving end, get a DatagramPacket containing the data.
There is no "connection" as with TCP.
The Clock Server
1 // In file network/ex3/ClockServer.java
2 import java.net.*;
3 import java.io.*;
4 import java.util.StringT
5 import java.util.V
6 import java.util.D
8 public class ClockServer {
public static final int REGISTRATION_PORT = 2001;
private final static int ADDR_BYTE_SIZE = 4;
private Vector mailingList = new Vector();
public static class AddressAndPort
implements Serializable {
private InetA
public AddressAndPort(InetAddress addr, int port) {
this.addr =
this.port =
public InetAddress getAddress() {
public int getPort() {
public boolean equals(Object o) {
if (o == null) {
AddressAndP
anp = (AddressAndPort)
catch (ClassCastException e) {
if (addr.equals(anp.addr) && port == anp.port) {
private class RegistrationService extends Thread {
public void run() {
listener =
new ServerSocket(REGISTRATION_PORT);
catch (IOException e) {
// Need to signal main thread that
// no one is getting registered.
for (;;) {
sock = listener.accept();
catch (IOException e) {
System.out.println(e.toString());
e.printStackTrace();
System.out.println("Got a connection.");
registerClient(sock);
listener.close();
catch (IOException e) {
private void registerClient(Socket sock) {
AddressAndP
// Grab the data from the client.
ObjectInputStream ois =
new ObjectInputStream(
new BufferedInputStream(
sock.getInputStream()));
anp = (AddressAndPort) ois.readObject();
catch (ClassNotFoundException e) {
// Just abort registering this client
System.out.println(e.toString());
e.printStackTrace();
catch (InvalidClassException e) {
// Just abort registering this client
System.out.println(e.toString());
e.printStackTrace();
catch (StreamCorruptedException e) {
// Just abort registering this client
System.out.println(e.toString());
e.printStackTrace();
catch (OptionalDataException e) {
// Just abort registering this client
System.out.println(e.toString());
e.printStackTrace();
catch (IOException e) {
// Just abort registering this client
System.out.println(e.toString());
e.printStackTrace();
sock.close();
catch (IOException e) {
synchronized (ClockServer.this) {
int len = mailingList.size();
boolean found =
for (int i = 0; i < ++i) {
Object o = mailingList.elementAt(i);
if (anp.equals(o)) {
System.out.println(
"Already registered: (" +
anp.getAddress().getHostAddress() +
", " + anp.getPort() + ")");
if (!found) {
mailingList.addElement(anp);
System.out.println("Registering: (" +
anp.getAddress().getHostAddress() + ", "
+ anp.getPort() + ")");
private class TickerService extends Thread {
public void run() {
sock = new DatagramSocket();
catch (SocketException e) {
System.out.println(e.toString());
e.printStackTrace();
for (;;) {
// Create the Datagram
Date date = new Date();
ByteArrayOutputStream baos =
new ByteArrayOutputStream();
ObjectOutputS
oos = new ObjectOutputStream(baos);
oos.writeObject(date);
oos.close();
catch (IOException e) {
byte[] data = baos.toByteArray();
synchronized (this) {
ml = (Vector) mailingList.clone();
int len = ml.size();
for (int i = 0; i < ++i) {
AddressAndPort anp =
(AddressAndPort) ml.elementAt(i);
InetAddress ia = anp.getAddress();
int port = anp.getPort();
DatagramPacket dp =
new DatagramPacket(data,
data.length, ia, port);
sock.send(dp);
catch (IOException e) {
System.out.println("Sending to port: " +
Thread.sleep(1000);
catch (InterruptedException e) {
private void start() {
RegistrationService rs = new RegistrationService();
rs.start();
TickerService ts = new TickerService();
ts.start();
public static void main(String[] args)
throws IOException {
ClockServer cs = new ClockServer();
cs.start();
The Clock Applet
1 // In file network/ex3/ClockApplet.java
2 import java.applet.*;
3 import java.net.*;
4 import java.io.*;
5 import java.awt.*;
6 import java.util.D
8 public class ClockApplet extends Applet {
private int myPort = 4000;
private CoolClockCanvas clock =
new CoolClockCanvas();
private class Runner extends Thread {
private boolean stopR
void requestStop() {
stopRequested =
public void run() {
for (;;) {
if (stopRequested) {
InetAddress ia =
InetAddress.getByName(null);
ClockServer.AddressAndPort myANP =
new ClockServer.AddressAndPort(
ia, myPort);
Socket sock = new Socket(ia,
ClockServer.REGISTRATION_PORT);
ObjectOutputStream oos =
new ObjectOutputStream(
new BufferedOutputStream(
sock.getOutputStream()));
oos.writeObject(myANP);
oos.close();
sock.close();
dgsock = new DatagramSocket(myPort);
catch (SocketException e) {
System.out.println(e.toString());
e.printStackTrace();
for (;;) {
int packetSize = 1000;
byte[] buf = new byte[packetSize];
DatagramPacket dp =
new DatagramPacket(
buf, packetSize);
dgsock.receive(dp);
System.out.println("Datagram received");
byte[] data = dp.getData();
ByteArrayInputStream bais =
new ByteArrayInputStream(data);
ObjectInputS
ois = new ObjectInputStream(bais);
date = (Date) ois.readObject();
ois.close();
catch (IOException e) {
System.out.println(e.toString());
e.printStackTrace();
catch (ClassNotFoundException e) {
System.out.println(e.toString());
e.printStackTrace();
clock.setTime(date);
catch (IOException e) {
System.out.println(e.toString());
e.printStackTrace();
public void init() {
String portStr = getParameter("port");
if (portStr != null) {
myPort = Integer.parseInt(portStr);
catch (NumberFormatException e) {
// Use default port number
setLayout(new BorderLayout());
add("Center", clock);
public synchronized void start() {
if (runner == null) {
runner = new Runner();
runner.start();
public synchronized void stop() {
if (runner != null) {
runner.requestStop();
1 // In file network/ex3/CoolClockCanvas.java
2 import java.awt.*;
3 import java.awt.event.*;
4 import java.util.*;
6 class CoolClockCanvas extends Canvas {
private Color backgroundColor = Color.lightG
private Color shadowColor = Color.
private Color tickShadowColor = Color.darkG
private int xCircleC
private int yCircleC
private int xSecondHandT
private int ySecondHandT
private int secondHandR
private Date latestDate = new Date();
CoolClockCanvas() {
setBackground(backgroundColor);
public void setTime(Date date) {
latestDate =
repaint();
private Point getHandTip(int radius, int minutePos) {
double thetaInD
if (minutePos
canvasSize.height) {
outerCircleDiameter = canvasSize.
outerCircleDiameter -= 8;
int xOuterCircle = (canvasSize.width -
outerCircleDiameter) / 2;
int yOuterCircle = (canvasSize.height -
outerCircleDiameter) / 2;
// Paint with background color first
og.setColor(backgroundColor);
og.fillRect(0, 0, canvasSize.width, canvasSize.height);
// Draw lines around the edge of the canvas, to give
// it the appearance of a sunken panel.
og.setColor(shadowColor);
og.drawLine(0, 0, 0, canvasSize.height - 1);
og.drawLine(0, 0, canvasSize.width - 1, 0);
og.setColor(Color.white);
og.drawLine(0, canvasSize.height - 1,
canvasSize.width - 1, canvasSize.height - 1);
og.drawLine(canvasSize.width - 1, 0,
canvasSize.width - 1, canvasSize.height - 1);
// Draw arcs around the face of the clock
// to give it a raised appearance.
og.setColor(Color.white);
og.drawArc(xOuterCircle, yOuterCircle,
outerCircleDiameter, outerCircleDiameter, 45, 180);
og.setColor(shadowColor);
og.drawArc(xOuterCircle, yOuterCircle,
outerCircleDiameter, outerCircleDiameter, 45, -180);
// Radius of tick marks is 4 pixels less than radius
// of outer circle
int fullRadius = (outerCircleDiameter / 2) - 4;
// Radius of tip of the second hand
secondHandRadius = fullRadius + 1;
int minuteHandRadius = secondHandR
int hourHandRadius = (fullRadius * 2) / 3;
xCircleCenter = xOuterCircle + (outerCircleDiameter / 2);
yCircleCenter = yOuterCircle + (outerCircleDiameter / 2);
// Calculate the absolute x and y positions for the
// tick marks that aren't at 12, 3, 6, or 9:00.
double shortSideDouble = ((double) fullRadius) *
Math.cos(Math.PI / 6.0);
double longSideDouble = ((double) fullRadius) *
Math.sin(Math.PI / 6.0);
int shortSide = (int) (shortSideDouble + 0.5);
int longSide = (int) (longSideDouble + 0.5);
// Put up 12 tick marks
drawTickMark(og, xCircleCenter, yCircleCenter - fullRadius);
drawTickMark(og, xCircleCenter + shortSide,
yCircleCenter - longSide);
drawTickMark(og, xCircleCenter + longSide,
yCircleCenter - shortSide);
drawTickMark(og, xCircleCenter + fullRadius, yCircleCenter);
drawTickMark(og, xCircleCenter + longSide,
yCircleCenter + shortSide);
drawTickMark(og, xCircleCenter + shortSide,
yCircleCenter + longSide);
drawTickMark(og, xCircleCenter, yCircleCenter + fullRadius);
drawTickMark(og, xCircleCenter - shortSide,
yCircleCenter + longSide);
drawTickMark(og, xCircleCenter - longSide,
yCircleCenter + shortSide);
drawTickMark(og, xCircleCenter - fullRadius, yCircleCenter);
drawTickMark(og, xCircleCenter - longSide,
yCircleCenter - shortSide);
drawTickMark(og, xCircleCenter - shortSide,
yCircleCenter - longSide);
Calendar cal = new GregorianCalendar();
cal.setTime(latestDate);
// Calculate the hour hand tip position
int hours = cal.get(Calendar.HOUR);
int minutes = cal.get(Calendar.MINUTE);
if (hours == 12) {
hours = 0;
int minPosOfHourHand = (hours * 5) + (minutes / 12);
Point hourHandTip = getHandTip(hourHandRadius,
minPosOfHourHand);
// Calculate the minute hand tip position
Point minuteHandTip = getHandTip(minuteHandRadius, minutes);
// Calculate the second hand tip position
int secs = cal.get(Calendar.SECOND);
Point secondHandTip = getHandTip(secondHandRadius, secs);
// Draw shadow of the 3 by 3 square in the center.
og.setColor(Color.black);
og.fillRect(xCircleCenter - 1, yCircleCenter - 1, 3, 3);
// Draw the hour hand
og.setColor(Color.blue);
og.drawLine(xCircleCenter, yCircleCenter,
hourHandTip.x, hourHandTip.y);
// Draw the minute hand
og.drawLine(xCircleCenter, yCircleCenter,
minuteHandTip.x, minuteHandTip.y);
// Draw a 2 by 2 square in the center on top
// of the shadow and hour and minute hands.
og.setColor(Color.red);
og.fillRect(xCircleCenter - 1, yCircleCenter - 1, 2, 2);
// Draw the second hand
og.drawLine(xCircleCenter, yCircleCenter,
secondHandTip.x, secondHandTip.y);
xSecondHandTip = secondHandTip.x;
ySecondHandTip = secondHandTip.y;
g.drawImage(offscreenImage, 0, 0, this);
private void drawTickMark(Graphics g, int x, int y) {
g.setColor(tickShadowColor);
g.fillRect(x, y, 2, 2);
g.setColor(Color.white);
g.fillRect(x, y, 1, 1);
Multicast Protocol
TCP and UDP are unicast protocols: there is only one sender and one
Multicast packets are UDP packets that can take an arbitrary number
of receivers.
Multicast uses "class D" IP addresses: 224.0.0.1 to 239.255.255.255.
Receivers "subscribe" to the multicast group (IP address).
Anyone can send to the group (not just subscribers). All subscribers are
eligible to receive the packet.
// Join a Multicast group.
InetAddress group = InetAddress.getByName("225.6.7.8");
MulticastSocket ms = new MulticastSocket(7000);
ms.joinGroup(group);
// Send the group a datagram. (Don't need to be a
// member to send to the group.)
byte[] msg = {'H', 'o', 'w', 'd', 'y'};
DatagramPacket dp = new DatagramPacket(msg,
msg.length, group, 7000);
ms.send(dp);
// Get a datagram from the group.
byte[] buf = new byte[1000];
DatagramPacket recv = new DatagramPacket(buf,
buf.length);
ms.receive(recv);
// Leave the group.
ms.leaveGroup(group);
URL and URLConnection
URL represents Uniform Resource Locator (a "pointer" to a
resource on the network).
URLConnection lets you interact with the resource.
Create URLConnection by invoking
openConnection() on a URL
Set up the URLConnection
Make the actual connection by invoking connect()
on the URLConnection
Interact with the header fields and contents of the resource.
URLStreamHandlers (for protocols) and
ContentHandlers (for MIME types) are loaded
dynamically when needed.
The Resource Grabber
1 // In file network/ex5/ResourceGrabber.java
2 import java.net.*;
3 import java.io.*;
4 import java.util.D
5 import java.util.StringT
7 public class ResourceGrabber {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println(
"Need URL and optional local filename.");
= new URL(args[0]);
System.out.println(
"Connecting to resource...");
URLConnection conn = url.openConnection();
InputStream is = url.openStream();
// Get info about the resource
String type = conn.getContentType();
Date date = new Date(conn.getLastModified());
String lastMod = date.toLocaleString();
// Print the info
System.out.println(
"Grabbing resource\n
type: " + type
last modified: " + lastMod);
FileOutputS
if (args.length < 2) {
String localFile =
// Grab the simple file name from the
// URL String
String fullPath = url.getFile();
StringTokenizer st =
new StringTokenizer(fullPath, "/");
while (st.hasMoreTokens()) {
localFile = st.nextToken();
fos = new FileOutputStream(localFile);
fos = new FileOutputStream(args[1]);
BufferedOutputStream bos =
new BufferedOutputStream(fos);
BufferedInputStream bis =
new BufferedInputStream(is);
int count = 0;
while ((c = bis.read()) != -1) {
bos.write(c);
if (count != 1) {
System.out.println(count
+ " bytes downloaded.");
System.out.println(
"1 byte downloaded.");
fos.close();
is.close();
catch (MalformedURLException e) {
System.err.println(e.toString());
e.printStackTrace();
catch (IOException e) {
System.err.println(e.toString());
e.printStackTrace();
Problem 1.
Write an application named GetServer.java that creates
a ServerSocket on port 80. When a client request comes
in, get an InputStream from the socket returned by
read lines from the ServerSocket's accept()
method, and wrap the InputStream in an InputStreamReader
and a BufferedReader. Read one line at a time from
the BufferedReader while the length of the line read
does not equal 0 and the first character is not '\r' or '\n'. Each time
you read a line from the BufferedReader, print the line
out to the standard output. Once you are done reading lines, just close
the socket by closing the BufferedReader.
What you'll end up printing out is HTTP requests sent by a web browser, which
are always terminated by a blank line, as in:
GET /jvm/index.html HTTP/1.0
Referer: http://minovia/subscribe.html
Connection: Keep-Alive
User-Agent: Mozilla/4.7 [en] (Win98; I)
Host: minovia
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
&BLANK LINE&
Start your GetServer application and then open a web browser.
Type in URLs into your browser's address bar such as:
http://127.0.0.1
http://127.0.0.1/this/is/a/longer/pathname/filename.html
Watch what output your GetServer prints and the web browser prints.
Problem 2.
Change your GetServer application from Problem 1 so that it also
sends a response back to the client. First, get an OutputStream from
the socket, and wrap that in a BufferedOutputStream and a
DataOutputStream. Write the following line out to the client
after reading in the HTTP request lines, and before closing the socket:
HTTP/1.0 404 Not found\r\n\r\n
Run your GetServer application again and look at what the web browser
now prints when you hit 127.0.0.1 URLs.
Problem 3.
Change your GetServer application from Problem 2 so that each time
a client request comes in, it fires off a new thread to handle the client.
Name the thread class ServerThread. Test
your application again with a web browser.
Problem 4.
Create a private instance method getFile() that returns
a String and takes no arguments in your
ServerThread class, and call the method from your
run() method right after getting the
DataOutputStream from the socket. Wrap the getFile()
invocation in a try block that has a catch (Exception e)
clause. In the catch clause, print the 404 Not Found
response back to the client.
Move the code that gets a BufferedReader from the socket to the
getFile() method. After getting the BufferedReader,
make sure that the first three
characters of the first line is "GET," as in:
GET /jvm/index.html HTTP/1.0
If the first three lines is not a GET, just throw an IOException
back to the run() method.
Finally, parse out the second token of that line, which in the above case would
be, "/jvm/index.html," and return that value from getFile().
Back in the main run() method of ServerThread, format an
HTTP request that indicates an HTML document is being returned:
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n\r\n
Finally, format the file name returned by
getFile() into an HTML page like this:
&TITLE&Requested File&/TITLE&
&H1&The requested file was: /jvm/index.html&/H1&
Write this HTML page out to the client after the 200 OK response.
Start your GetServer once again and hit 127.0.0.1
URLs with your web browser.
Problem 5.
Please enhance your GetServer application yet again. Change the
return value of getFile() to a java.io.File. Modify
getFile() so that it returns an actual full path to the file
requested in the GET, based on a hard-coded base directory.
For your hard-coded base directory, select some directory that has web
pages in it, such as the directory in which you installed your javadoc documentation.
If the requested path turns out to be a directory, just append index.html
to the path.
Back in the run() method, adjust the code so that the full
path is printed out in the web page sent back to the client, such as:
&TITLE&Requested File&/TITLE&
&H1&The requested file was: d:\hard\coded\dir\jvm\index.html&/H1&
Problem 6.
Lastly, change the run() method such that it actually sends back
an approprite MIME type and the actual file contents.
First, create a new java.util.HashMap in the GetServer's
main() method, and add to it the MIME types for several file extensions:
text/plain
image/jpeg
Pass a reference to this HashMap to the constructor of every ServerThread.
In the ServerThread's run() method, figure out the appropriate MIME type
by looking up the file's extension in the Map passed to the ServerThread's
constructor. Send that MIME type back to the client in the Content-Type header rather
than just text/html. If you don't recognize the file extension, just use the MIME
type text/plain.
In addition to Content-Type, send back a Content-Length header that
indicates the length of the file to follow, as in:
HTTP/1.1 200 OK\r\n
Content-Length: 92\r\n
Content-Type: image/gif\r\n\r\n
Lastly, create a FileInputStream for the File returned by getFile(),
and wraps the FileInputStream in a BufferedInputStream. Then read bytes
from the file and write them to the socket. When your done, just close both the socket and the file,
and return from the run() method.
Artima, Inc. All Rights Reserved. -}

我要回帖

更多关于 120.25.77.241 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信