SDSU CS 580 Client-Server
Spring Semester, 2004
Some on Protocol
Previous    Lecture Notes Index    Next    
© 2004, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 30-Mar-04


Java Network Programming, Harold, O’Reilly, pp 75-116

VisualWorks Internet Client Developer’ Guide, pp 24-48

Doc 21, Some on Protocol Slide # 2

Some low level Parsing

Java String methods


Returns an array of String { “cat”, “man”, “ran”);

for valid arguments of split().


parts = new java.util.StringTokenizer("cat,man;ran;,fan", ",;");
while (parts.hasMoreElements()) 
   System.out.println( parts.nextToken());


Doc 21, Some on Protocol Slide # 3
Some Useful Smalltalk Collection Methods

'cat;man;ran' tokensBasedOn: $;

OrderedCollection ('cat' 'man' 'ran')

'cat. man... ran.'
            [:each :next | each = $. and: [next = Character space]] 
      do: [:each | Transcript show: each printString; cr]


' man...'
' ran.'

Doc 21, Some on Protocol Slide # 4
Some Useful Smalltalk Collection Methods

      runsFailing: [:each | each = $\] 
      do: [:each | Transcript show: each; cr]



      runsSatisfying: [:each | each ~= $\] 
      do: [:each | Transcript show: each; cr]



Doc 21, Some on Protocol Slide # 5
Java Streams

Java Streams do not have many methods that aid in parsing

Avoid PrintStream – println() is platform dependent

“PrintStream is evil and network programmers should avoid it like the plague”


Text claims that readLine() is buggy

Avoid using this method to read data from a socket

Data Input/Output Streams

Are used for binary data

Don’t use unless protocol is binary

If protocol is binary these streams are only good between Java clients and servers

Doc 21, Some on Protocol Slide # 6
Smalltalk Streams – Some Useful Methods


peekFor: anObject

skipToAll: aCollection

throughAll: aCollection

upTo: anObject

upToAll: aCollection

skipUpTo: anObject

Doc 21, Some on Protocol Slide # 7
upToAll: and Java

upToAll: is a useful method

Reads up to a given string in a stream or string

read = new"catEOMmatEOM", "EOM")
while (read.hasMoreElements() ) 
   System.out.println( read.readChunk());


Doc 21, Some on Protocol Slide # 8

Calendar System

Anonymous Users

Search on

Registered Users

After login on with user name and password can


An event has

Partial Sample Protocol

Request General Format

requestName CRLF
key1=value1 CRLF
key2=value2 CRLF


login CRLF
user=whitney CRLF
password=foobar CRLF

newEvent CRLF
title=The Emerging Cyberinfrastructure CRLF
start=April 2, 2004 11:00 CRLF
duration=60 CRLF
location=GMCS 327 CRLF
owner=whitney CRLF

Some issues are not specified on purpose

Doc 21, Some on Protocol Slide # 9
How to Handle Protocol


Represents a Logon request
Can generate valid Calendar logon protocol request string
Can read valid Calendar logon protocol request

Doc 21, Some on Protocol Slide # 10
Java Example

public class CalendarLogonRequest {
   private Hashtable data = new Hashtable();

   public void userName( String name) { data.put(“user”, name); }

   public String userName()  { return data.get(“user”); }

   public void password(String password) {
      data.put(“password”, password);

   public String toString() {
      StringBuffer logon = new StringBuffer();
      logon.append(“login” ).
      logon.append(“\r\n” ).
      logon.append(“user=” ).
      logon.append( data.get(“user”) ).
      logon.append(“\r\n” ).
      logon.append(“password=” ).
      logon.append( data.get(“password”) ).
      logon.append(“\r\n” ).
      return logon.toString();
   public static CalendarLogonRequest from(InputStream in) {
      parse in
      return CalendarLogonRequest object with username and password set}

Doc 21, Some on Protocol Slide # 11
Smalltalk Example

Smalltalk defineClass: #CalendarLogonRequest
   superclass: #{Core.Object}
   indexedType: #none
   private: false
   instanceVariableNames: 'userName password '
   classInstanceVariableNames: ''
   imports: ''
   category: 'Protocol Examples'

CalendarLogonRequest class methods

from: aStringOrReadStream
   ^super new from: aStringOrReadStream readStream

userName: aNameString password: aPasswordString
   ^super new setUserName: aNameString password: aPasswordString 

CalendarLogonRequest Instance methods

setUserName: aNameString password: aPasswordString
   userName := aNameString.
   password := aPasswordString 

from: aReadStream
   | message lines |
   message := aReadStream upToAll: 'EOM\' withCRs.
   lines := message tokensBasedOn: Character cr.
   lines do: 
      [:each | (each includes: $=) ifTrue:[self addPairFrom: each]]

Doc 21, Some on Protocol Slide # 12

addPairFrom: aString
   | keyValue |
   keyValue := aString tokensBasedOn: $=.
   keyValue first asLowercase = 'password' 
      ifTrue:[ password := keyValue last].
   keyValue first asLowercase = 'user' 
      ifTrue:[ userName := keyValue last].

   | aStream |
   aStream := WriteStream on: (String new: 16).
   self printOn: aStream.
   ^aStream contents

printOn: aStream
      nextPutAll: 'login'; cr;
      nextPutAll: 'user=';
      nextPutAll: userName; cr;
      nextPutAll: 'password=';
      nextPutAll: password; cr;
      nextPutAll: 'EOM'; cr



Doc 21, Some on Protocol Slide # 13
What is the Point?

Use CalendarLogonRequest to generate logon protocol

logonRequest = new CalendarLogonRequest();
logonRequest.user( “whitney”);
logonRequest.password( “foo” );
clientSocket = new Socket(“”, 9009);
toServer = clientSocket.getOutputStream();
request = logonRequest.toString();

Use CalendarLogonRequest to read protocol on server side

Doc 21, Some on Protocol Slide # 14
Sample Client

clientSocket := SocketAccessor newTCPclientToHost: '' port: 9009.
logon := CalendarLogonRequest userName: 'roger' password: 'foo'.
toServer := clientSocket readAppendStream.
toServer lineEndCRLF.
toServer nextPutAll: logon asString;flush.

Sample Server

server := SocketAccessor newTCPserverAtPort: 9009.
server listenFor: 5.
acceptedSocket := server accept.
[ | stream |
   stream := acceptedSocket readAppendStream.
   stream lineEndCRLF.
   request := CalendarLogonRequest from: stream.
   stream nextPutAll: 'Done'; commit.
      stream close. 
   ] forkAt: Processor userSchedulingPriority -1.

Doc 21, Some on Protocol Slide # 15
Second Idea – Command

One the server side let the request actually perform the operation

public class CalendarLogonRequest {

   public Result execute( CalenderHandler aCalender) {
      check to see if user name and password are correct
      return a result object

Doc 21, Some on Protocol Slide # 16
Third Idea – Protocol Stream

Create a CalendarInputStream

public void run(int port) throws IOException {
      ServerSocket input = new ServerSocket( port );"Server running on port " + input.getLocalPort());
      while (true) {
         Socket client = input.accept();"Request from " + client.getInetAddress());
            new CalenderInputStream(client.getInputStream()),
            new CalenderOutPutStream(client.getOutputStream());

void processRequest(
            CalenderInputStream in, 
            CalenderOutPutStream out)
      throws IOException {
      CalenderRequest request = (CalenderRequest );
      CalenderRequest response = request.execute( calender );
      out.write( response);

Doc 21, Some on Protocol Slide # 17
Issue – Which Request?

Socket client = input.accept();
in = client.getInputStream();

String firstLine = in.readLine();
if (firstLine = “login” )
   request = new CalendarLoginRequest();
else if (firstLine = “newEvent” )
   request = new CalendarNewEventRequest();
else if etc.

Can Use Prototype

requests = new Hashtable();
requests.put( “login”, new CalendarLoginRequest());
requests.put(“newEvent”, new CalendarNewEventRequest());

Socket client = input.accept();
in = client.getInputStream();

String firstLine = in.readLine();
request = requests.get( firstLine).clone();

Copyright ©, All rights reserved.
2004 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.

Previous    visitors since 30-Mar-04    Next