CSE 132 (Spring 2010)
Studio 6: Streams, Sockets, and Caesar's Cipher

Review studio procedures, if necessary, before starting.

Some guidelines for this week's studio:

All groups do the following

I wrote this class with you during lecture. Take a look at its getInputStream(int numWords) method. It shows how an InputStream is formed and the role of the read method.
  • Run the PreambleTest and take a look at the output. Make sure you understand why you see what you see. There is a loop printing out each byte as it is received and a String that is printed at the end. The String is the concatenation of all of the bytes received.
  • Why does the method return -1 when there are no more characters left?
  • Be prepared to explain how this class works to the TA.

Sender or Receiver?

Sender (Client)

  1. As a group, decide on an encryption shift value n for your Caesar cipher.
    The number you choose must be such that 1≤n≤25.
    Keep your number a secret within your group.
  2. Write a class Adapter
    Your work from here on should go into the run() method of the Sender class.
  3. Test your Adapter on 20 words or so by:
    Adapter io = new Adapter(new Preamble().getInputStream(20), System.out);
    You should see the preamble words printing out in your console.
  4. Show your Adapter to other groups or to a TA.
  5. Write a similar class ForkStream

OK now let's try sending the Preamble to your Receiver group.

  1. Create a Socket connection to your Receiver's machine, using the host name and port number that they tell you.
  2. Use your Adapter to connect from the Preamble input stream to the Socket's output stream.
    • The Receiver group must be running their application or your code will fail to connect to the server socket. They should run their application first and then you should launch yours.
    • Recall how to get the Socket's output stream.
  3. When you execute your .run() of your Adapter, they should receive the information you are sending in clear text (unencrypted).
  4. Verify that they are seeing this.
  5. Now use your ForkStream class to connect the Preamble to both the Socket OuptutStream and to System.out.
    Now you can see what's beeing sent as well.

Now we encrypt!

  1. Modify your ForkStream so that each byte of the input stream is run through a Crypto object's encrypt(char). method before sending the byte to the output streams. The Crypto object should be suitably instantiated with your secret shift value.
    You will have to cast the int to a byte for encrypt to accept it.
    Try sending to the Receiver again. You should both be seeing the encrypted version.
  2. Change ForkStream so you see the clear text version but the Receiver continues to see the encrypted version.
    Did the Receiver team correctly guess your encryption key?
  3. Once they are good at that, and can decrypt messages, change your key and try this again.
  4. Now try sending messages you type in yourself, by prompting yourself for a String using
    JOptionPane.showInputDialog(String prompt)
  5. You probably don't want to close the connection after each message, but you probably should flush() so your message gets sent right away.
    Arrange for your Sender to keep sending until a particular string is typed.

Receiver (Server)

  1. Find out your machine's host name using the technique shown in class.
  2. Decide on a port address at which you will offer your service.
    I checked out the machines in the attic, and at least port 3000 is available. If you have trouble offering service on that port at some point, you can try another.
  3. Be prepared to tell other groups your host name and the port address at which you will offer service.

First we try to receive clear text

Your work from here on should go into the run() method of the Receiver class.
  1. Instantiate a ServerSocket at the port address.
  2. Write code to accept() on the ServerSocket.
  3. Get the resulting Socket's InputStream.
  4. Write an Adapter class, using the specification given above for the Sender.
  5. Use the Adapter to connect the Socket's InputStream to System.out. This will let you see the messages that are sent.
  6. Verify that you are receiving the text sent by your Sender group.
    If your other group is not ready, try to find a group that is and interact with them to test this out so you can move forward.

Now we prepare for the encrypted messages.

  1. The Sender will send messages using a Caesar cipher.
    Your job is to analyze the messages coming across the Socket and determine the value of the key for the cipher. The key value will be in the range 1≤n≤25.
  2. Figure out as a group how to determine the value of the shift.
    • Some ideas were given in class.
    • Write a class that analyzes properties of interest concerning the text you are receiving.

    It is not acceptable to try all 25 keys at once. You must show the TAs that you have cleverly determined the key.

Now try to decrypt the messages.

  1. Keep asking your Sender group to send you messages of a length you specify. It is unfair to ask them to send a particular message.
  2. Once you believe you know the cipher key, interpose an instance of a Crypto object with the key and use its decrypt message in your Adapter class to process each byte so you can (try to) see the clear text.

Further Investigations

Last modified 08:59:28 CDT 03 June 2010 by Ron K. Cytron