Name:

SE550 midterm exam: Autumn 2001-2002

Answer all questions.

Time allowed: 2 hours

Total number of points: 100

Finger server

Some questions will refer to a Finger server. It is defined here.

public class FingerServer implements Runnable {

    public static void main (final String[] args) throws IOException {        
        final ServerSocket sSocket = new ServerSocket (2000);
        while (true) {
            final Socket socket = sSocket.accept ();
            final FingerServer server = new FingerServer (socket);
            server.start ();
        }
    }

    protected final static Hashtable users = new Hashtable ();

    protected final Socket socket;
    protected final PrintWriter out;
    protected final BufferedReader in;
    protected final Thread thread;

    protected FingerServer (final Socket socket) throws IOException {
        this.socket = socket;
        this.out = new PrintWriter (socket.getOutputStream (), true);
        this.in = new BufferedReader (new InputStreamReader (socket.getInputStream ()));
        this.thread = new Thread (this);
    }

    public void start () { thread.start (); }

    public void run () {
        try {
            String line = in.readLine (); 
            while (line != null && !line.equals ("QUIT")) {
                if (line.startsWith ("LOGIN ")) {
                    login (line.substring (6));
                } else if (line.startsWith ("LOGOUT ")) {
                    logout (line.substring (7));
                } else if (line.startsWith ("FINGER ")) {
                    finger (line.substring (7));
                } else {
                    error ();
                }
                line = in.readLine ();
                }
        } catch (final IOException ex) {
        } finally {
            try {
                out.close ();
                in.close ();
                socket.close ();
            } catch (final IOException ex) {
            }
        }
    }

Finger server continued

    protected void login (final String userid) {
        // Create a new Date object containing the current
        // date and time
        final Date now = new Date ();
        users.put (userid, now);
        out.println (userid + " LOGGED IN " + now);
    }

    protected void logout (final String userid) {
        final Date loginDate = (Date)(users.get (userid));
        if (loginDate == null) {
            out.println (userid + " NOT LOGGED IN");
        } else {
            users.remove (userid);
            out.println (userid + " LOGGED OUT");
        }
    }

    protected void finger (final String userid) {
        final Date loginDate = (Date)(users.get (userid));
        if (loginDate == null) {
            out.println (userid + " NOT LOGGED IN");
        } else {
            out.println (userid + " LOGGED IN " + loginDate);
        }
    }

    protected void error () {
        out.println ("ERROR");
    }

}

Finger login client

public class FingerLoginClient {

    public static void main (final String[] args) {

        try {
            final Socket socket = new Socket (args[0], 2000);
            final String userid = args[1];
            final PrintWriter out = new PrintWriter (socket.getOutputStream (), true);
            final BufferedReader in = new BufferedReader (new InputStreamReader (socket.getInputStream ()));
            out.println ("LOGIN " + userid);
            final String response = in.readLine ();
            if (response.startsWith (userid + " LOGGED IN ")) {
                final String date = response.substring (userid.length () + 11);
                System.out.println ("Logged in " + userid + " succeeded at " + date);
            } else {
                System.err.println ("Logging in " + userid + " failed");
                System.exit (1);
            } 
            out.println ("QUIT");
            out.close ();
            in.close ();
            socket.close ();
        } catch (final IOException ex) {
            System.err.println ("Network error: " + ex);
            System.exit (1);
        }
    }

}

Finger server continued

PARSER_BEGIN (FingerRequestParser)
public class FingerRequestParser {
    public void handleQuitRequest () { code for a QUIT request }
    public void handleLoginRequest (String userid) { code for a LOGIN request }
    public void handleFingerRequest (String userid) { code for a FINGER request }
    public void handleLogoutRequest (String userid) { code for a LOGOUT request }
}
PARSER_END (FingerRequestParser)

TOKEN : {
  <QUIT: "QUIT">
| <LOGIN: "LOGIN">
| <LOGOUT: "LOGOUT">
| <FINGER: "FINGER">
| <CRLF: "\n" | "\r" | "\n\r">
| <SPACE: " ">
| <STRING: ( ~["\n","\r"] )+>
}

void request () : {} {
    loginRequest () | logoutRequest () | fingerRequest () | quitRequest ()
}

void loginRequest () : {
    String userid;
}{
    <LOGIN> <SPACE> userid = string () <CRLF>
    { handleLoginRequest (userid); }
}

void logoutRequest () : {
    String userid;
}{
    <LOGOUT> <SPACE> userid = string () <CRLF>
    { handleLogoutRequest (userid); }
}

void fingerRequest () : {
    String userid;
}{
    <FINGER> <SPACE> userid = string () <CRLF>
    { handleFingerRequest (userid); }
}

void quitRequest () : {} {
    ( <QUIT> <CRLF> ) | <EOF>
    { handleQuitRequest (); }
}

String string () : {
    Token t;
}{
    t = <STRING>
    { return t.image; }
}

Question 1 (10 points)

a) What is a lossy protocol? Is TCP lossy? Is IP lossy?

b) What is an ordered protocol? Is TCP ordered? Is IP ordered?

c) What is a stream-based protocol? Is TCP stream-based? Is IP stream based?

d) What role does DNS play in an IP-based network?

Question 2 (10 points)

Assume that on machine server the following command is run:

  java FingerServer

and that on machine client the following command is run:

  (At 11.14am on 10/16/2001):
    java FingerLoginClient server wilma
  (At 11.17am on 10/16/2001):
    java FingerLoginClient server fred
  (At 11.21am on 10/16/2001):
    java FingerLoginClient server wilma

a) What messages are sent between the client and the server (assuming no network problems)?

b) What are the contents of FingerServer.users after the messages are sent.

For purposes of this and subsequent questions, you can assume that when a Date object is printed out, it uses the format:

   MM/DD/YYYY HH:MM:SS

for example:

  10/16/2001 11:14:00
  01/01/2001 02:03:04
  12/31/2001 23:59:59

Question 2 continued

Question 3 (10 points)

If a client sends the following requests to the FingerServer, what responses will be returned?

  (At 1.45pm on 1/1/2000):
  LOGIN barney






  (At 1.46pm on 1/1/2000):
  LOGIN betty






  (At 1.47pm on 1/1/2000):
  FINGER barney






  (At 1.48pm on 1/1/2000):
  LOGOUT barney





  (At 1.49pm on 1/1/2000):
  LOGOUT wilma





  (At 1.50pm on 1/1/2000):
  FINGER barney





  (At 1.51pm on 1/1/2000):
  GET /index.html HTTP/1.0




  (At 1.52pm on 1/1/2000):
  QUIT

Question 4 (20 points)

The client code only allows users to log in and doesn't allow users to be fingered, or users to log out.

a) Write a client which allows users to log out. This should produce the message Logged out OK if logging out succeeded, Not logged in! if the user was not currently logged in, and Oh dear... if a different error occurred.

public class FingerLogoutClient {

    public static void main (final String[] args) {

        try {
            final Socket socket = new Socket (args[0], 2000);
            final String userid = args[1];
            final PrintWriter out = new PrintWriter (socket.getOutputStream (), true);
            final BufferedReader in = new BufferedReader (new InputStreamReader (socket.getInputStream ()));































            out.close ();
            in.close ();
            socket.close ();
        } catch (final IOException ex) {
            System.err.println ("Network error: " + ex);
            System.exit (1);
        }
    }

}

Question 4 continued

b) Write a client which fingers other users.

This should produce the message Logged on at MM/DD/YYYY HH:MM:SS if fingering succeeded, Not logged in! if the user was not currently logged in, and Oh dear... if a different error occurred.

public class FingerFingerClient {

    public static void main (final String[] args) {

        try {
            final Socket socket = new Socket (args[0], 2000);
            final String userid = args[1];
            final PrintWriter out = new PrintWriter (socket.getOutputStream (), true);
            final BufferedReader in = new BufferedReader (new InputStreamReader (socket.getInputStream ()));
































            out.close ();
            in.close ();
            socket.close ();
        } catch (final IOException ex) {
            System.err.println ("Network error: " + ex);
            System.exit (1);
        }
    }

}

Question 5 (20 points)

Give two grammars for the protocol which is used by the Finger clients and server.

(For purposes of this question, you can assume that userids can contain any characters other than spaces and new line characters.)

a) Your first grammar should define a nonterminal <request>, which defines the language of requests sent by the clients.

Question 5 continued

b) Your second grammar should define a nonterminal <response>, which defines the language of responses sent by the server.

Question 6 (20 points)

The JavaCC parser FingerRequestParser gives a parser for requests. Write a parser for responses.

PARSER_BEGIN (FingerResponseParser)
public class FingerResponseParser {
    public void handleLoggedInResponse (String userid, String time) { code for an LOGGED ON response }
    public void handleNotLoggedInResponse (String userid) { code for a NOT LOGGED IN response }
    public void handleLoggedOutResponse (String userid) { code for a LOGGED OUT response }
    public void handleErrorResponse () { code for an ERROR response }
}

PARSER_END (FingerResponseParser)

TOKEN : {
  <ERROR: "ERROR">
| <LOGGED: "LOGGED">
| <IN: "IN">
| <OUT: "OUT">
| <NOT: "NOT">
| <ERROR: "ERROR">
| <COLON: ":">
| <SLASH: "/">
| <CRLF: "\n" | "\r" | "\n\r">
| <SPACE: " ">
| <DIGIT: ["0"-"9"]>
| <STRING: ( ~["\n","\r"," "] )+>
}

// your code goes here

Question 6 continued

Question 7 (10 points)

a) What is a lexer?

b) What is a parser?

c) What is a parser generator?

e) Give one advantage and one disadvantage of using a parser generator rather than writing a parser by hand.

Worksheet

You can use this sheet as scrap paper.

Worksheet

You can use this sheet as scrap paper.

Worksheet

You can use this sheet as scrap paper.

Worksheet

You can use this sheet as scrap paper.