Big Java Lab 24

Sockets

1.

Write a program that uses a socket to retrieve the correct time from a timeserver using the DAYTIME protocol.

There are many servers on the Internet that provide a time service. The National Institute of Standards and Technology http://www.bldrdoc.gov/ maintains several timeservers that allow users to synchronize a clock. One protocol used is the Daytime protocol. The Daytime protocol is a simple protocol. The user connects on port 13 and sends a newline character. The server responds by sending back an ASCII string and then disconnects. The time string from the NIST servers is in the following format:

JJJJJ YR-MO-DA HH:MM:SS TT L H msADV UTC(NIST) *

In this simple exercise, we are concerned only with the first half of the string.

JJJJJ represents the last five digits of the Julian date. You can ignore this value.

YR-MO-DA YR represents the last two digits of the year, MO represents the month and DA, the current day.

HH:MM:SS is the time in hours (HH), minutes (MM) and seconds (SS). This is sent in Coordinated Universal time.

You need to add an offset to correct the time to your time zone.

Write a program that connects to three of the NIST servers listed below, using the Daytime protocol. Parse the return string and create a Date object set to the return string's time. Print out the return strings and your Date objects. Use a SimpleDateFormat to format your date. Make sure you adjust the time to your correct time zone. You should read the Java API documentation to obtain more information on the SimpleDateFormat class. Basically you will need to use the class to parse the string (or substring of) returned by the server. For example, the following formatter is able to format a string of the form "05-02-25 17:30:49 UTP", by using its parse method:

SimpleDateFormat formatter = new SimpleDateFormat("yy-MM-dd HH:mm:ss z");

After obtaining a Date object using formatter.parse, you can format it to your local time using the format method of the DateFormat class:

DateFormat localFormatter = DateFormat.getDateTimeInstance();

NIST Timeservers

Name

Location

time-a.nist.gov

NIST, Gaithersburg, Maryland

time-b.nist.gov

NIST, Gaithersburg, Maryland

time-a.timefreq.bldrdoc.gov

NIST, Boulder, Colorado

time-b.timefreq.bldrdoc.gov

NIST, Boulder, Colorado

time-c.timefreq.bldrdoc.gov

NIST, Boulder, Colorado

utcnist.colorado.edu

University of Colorado, Boulder

time.nist.gov

NCAR, Boulder, Colorado

time-nw.nist.gov

Microsoft, Redmond, Washington

nist1.datum.com

Datum, San Jose, California

nist1.dc.glassey.com

Abovenet, Virginia

nist1.ny.glassey.com

Abovenet, New York City

nist1.sj.glassey.com

Abovenet, San Jose, California

nist1.aol-ca.truetime.com

TrueTime, AOL facility, Sunnyvale, California

nist1.aol-va.truetime.com

TrueTime, AOL facility, Virginia

What is the code of your program?


2.

Modify your previous program so that it uses the TIME protocol instead of the DAYTIME protocol. To use the Time protocol, a user connects on port 37 and sends a newline character. The server responds by returning a 32-bit unformatted binary number that represents the time in UTC seconds since January 1, 1900.

Hints:

Unlike the C language, Java does not have an unsigned data type to represent an unsigned 32-bit binary number. An int in Java represents a 32-bit signed binary number. Usually a larger type, in this case a long, is used to store an unsigned int. The time server sends four bytes that represent an unsigned int, which you will have to store in a long. Instead of using a scanner, you will need to read an array of bytes using the input stream directly:

byte[] b = new byte[4];

instream.read(b);

Then, you will need to convert the byte array to a long. You can use the following method for the purpose:

public static final long unsignedIntToLong(byte[] b)
{
    long l = 0;
    l |= b[0] & 0xFF;
    l <<= 8;
    l |= b[1] & 0xFF;
    l <<= 8;
    l |= b[2] & 0xFF;
    l <<= 8;
    l |= b[3] & 0xFF;
    return l;
}

Java stores dates as the number of milliseconds since January 1, 1970. The Time protocol returns the number of seconds since January 1, 1900. To compute the difference, create a GregorianCalendar object that represents 01/01/1970 and a GregorianCalendar object that represents 01/01/1900. Call getTimeInMillis() on each to retrieve the milliseconds. Then subtract to find the difference. Convert the difference to seconds and add it to the return value. Convert the corrected return value to milliseconds to create your Date object.

Client/Server

3.

Create a server application that uses the following protocol:

Client Request

Server Response

Meaning

HELLO

greeting

Sends a greeting

ECHO n

n

Echoes n back to the client

COUNT

The number of ECHO requests

Returns a count of the number of ECHO requests by client

QUIT

goodbye

Prints a goodbye and quits the connection

You may choose the greeting and goodbye messages to send. In this exercise you will create three classes:

SimpleProtocolService

SimpleProtocolServer

SimpleProtocolClient

The server should accept multiple simultaneous connections with different clients.

What is the code of your SimpleProtocolService class? Part of the code of the class has been provided for you:

public class SimpleProtocolService implements Runnable
{
public SimpleProtocolService(Socket aSocket) { . . . }

public void run()
{
       try
       {
          try
          {
             in = new Scanner(s.getInputStream());
             out = new PrintWriter(s.getOutputStream());
             doService();
          }
          finally
          {
             s.close();
          }
       }
       catch (IOException exception)
       {
          exception.printStackTrace();
       }
    }
    public void doService() throws IOException { . . . }
    public void executeCommand(String command) { . . . }
    . . .

}


4.

To support multiple simultaneous connections, construct a new thread to communicate with each client. What is the code of your SimpleProtocolServer class?


5.

Write a client that connects to the server, sends several commands and disconnects. What is the code of your SimpleProtocolClient class?

URL Connections

6.

Write a program that gets a weather report for your state. The URL is

http://iwin.nws.noaa.gov/iwin/xy/hourly.html

where xy is a 2-letter state abbreviation such as ca or ny.

Your program should get the data from the web site and strip out all HTML formatting, printing just the raw weather report.


7.

What is the output of your program if the URL points to an invalid location? (for example, http://iwin.nws.noaa.gov/iwin/ev/hourly.html)

Tic-tac-toe

8.

In this section, we will create a server application that allows two players to play tic-tac-toe against each other.

Design and implement a protocol to play tic-tac-toe.

  • A player can connect, give the player name, and wait for an opponent.
  • When two opponents have connected, the server picks one of them to start playing.
  • The active player must be able to transmit a move to the server. The server checks that the move is valid. If the last move finishes the game, the server pronounces the winner.
  • The server notifies both players of the new board position, and, if the game is not yet over, asks the opponent to play.

Simply number the rows and columns and communicate moves with the row and column numbers.

What are the client requests and server responses in your protocol?


9.

What is the code of your TicTacToeServer class?

10.

What is the code of your TicTacToeServer class?


11.

What is the code of your TicTacToeClient class?