import java.net.*; import java.io.*; import sdsu.io.ASCIIInputStream; class SPOPServer { static int portNumber = 4444; public static void main(String args[]) { ServerSocket serverSocket; serverSocket = serverSocketOn( portNumber ); Socket clientSocket = null; InputStream fromClient; OutputStream toClient; while ( true ) { clientSocket = acceptClientRequestOn( serverSocket ); fromClient = inputStreamFromClient( clientSocket ); toClient = outputStreamToClient( clientSocket ); processClientRequest( fromClient, toClient ); } }
protected static ServerSocket serverSocketOn( int portNumber ) { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket( portNumber ); } catch (IOException e) { System.out.println("Could not listen on port: " + ", " + e); System.exit(1); } return serverSocket; } protected static Socket acceptClientRequestOn( ServerSocket server) { Socket clientSocket = null; try { clientSocket = server.accept(); } catch (IOException e) { System.out.println("Accept failed: " + ", " + e); System.exit(1); } return clientSocket; } protected static InputStream inputStreamFromClient( Socket client ) { InputStream inputSocketStream; BufferedInputStream bufferedInputSocketStream = null; try { inputSocketStream = client.getInputStream(); bufferedInputSocketStream = new BufferedInputStream( inputSocketStream ); } catch ( IOException e) { // What to do here? } return bufferedInputSocketStream; } protected static OutputStream outputStreamToClient( Socket client ) { OutputStream outputSocketStream; BufferedOutputStream bufferedOutputSocketStream = null; try { outputSocketStream = client.getOutputStream(); bufferedOutputSocketStream = new BufferedOutputStream( outputSocketStream, 1024 ); } catch ( IOException e) { // What to do here? } return bufferedOutputSocketStream; } protected static void processClientRequest( InputStream in, OutputStream out ) { SPOPHandler mail = new SPOPHandler( in, out); Thread serverThread = new Thread( mail, "Mail Server" ); serverThread.start(); }
public class SPOPHandler { protected SPOPState currentState = new NoAuth( ); protected SPOPInputStream cin; protected SPOPOutputStream cout; public SPOPHandler( InputStream in, OutputStream out ) { cin = new SPOPInputStream( cin ); cout = new SPOPOutputStream( cout ); } public void run( ) { while !( currentState instanceof Quit ) { SPOP_Command clientRequest; SPOP_Response serverResponse; cin.read( clientRequest ); currentState = getServerResponse( clientRequest , serverResponse ); cout.write( serverResponse ); } // In quit state, close connection cin.close; cout.close; } protected SPOPState getServerResponse( SPOP_Command request, SPOP_Response serverResponse) { SPOPState nextState; String command = request.command(); if ( command.compareTo( "USER" ) == 0 ) nextState = currentState.USER( request, serverResponse ); else if ( command.compareTo( "PASS" ) == 0 ) nextState = currentState.PASS( request, serverResponse ); else if ( command.compareTo( "LIST" ) == 0 ) nextState = currentState.LIST( request, serverResponse ); else if ( command.compareTo( "QUIT" ) == 0 ) nextState = currentState.QUIT( request, serverResponse ); else { //create an error message here serverResponse = error messsage } return nextState; } }
public class SPOP_Command { protected static final String EndOfCommand = "\r\n"; protected static final String Separator = " "; protected String command = " "; // avoid null string protected String argument = " "; // problems public SPOP_Command( String aCommand ) { command = aCommand ; } public setArgument( String SpopArgument) { argument = SpopArgument; } public String command() { return command; } public String argument() { return argument; } // Produce a string representation of command object public String toString() { return command() + Separator + argument() + EndOfCommand; } // return a command object from string represention of // command public static SPOP_Command fromString( String message ) { StringTokenizer messageParser; messageParser = new StringTokenizer( message, Separator ); String commandPart = messageParser.nextToken(); String argumentPart = messageParser.nextToken(); SPOP_Command commandFromString; commandFromString = new SPOP_Command( commandPart ); commandFromString.argument( argumentPart ); return commandFromString; }
public class SPOP_Response { // See POP3 for these constants protected static final String EndOfCommand = "\r\n.\r\n"; protected static final String Separator = "\r\n"; protected String statusMessage = " "; protected String data = " "; public SPOP_Response( String status ) { statusMessage = status ; } public setData( String information) { data = information; } public String status() { return statusMessage ; } public String data() { return data; } // Produce a string representation of response object public String toString() { return status() + Separator + data() + EndOfCommand; } // return a command object from string represention of // command public static SPOP_Command fromString( String message ) { StringTokenizer messageParser; messageParser = new StringTokenizer( message, Separator ); String statusPart = messageParser.nextToken(); String dataPart = messageParser.nextToken(); SPOP_Response responseFromString; responseFromString = new SPOP_Response( statusPart ); responseFromString.argument( dataPart ); return responseFromString; }
class SPOPOutputStream extends OutputStream { PrintStream cout; public SPOPOutputStream( OutputStream out ) { cout = new PrintStream( out ); } public void print( SPOP_Command aCommand) { String message = aCommand.asString(); cout.print( message ); cout.flush(); } public void print( SPOP_Response aResponse ) { String message = aResponse.asString(); cout.print( message ); cout.flush(); } }
class SPOPInputStream extends InputStream { ASCIIInputStream cin; public SPOPInputStream( InputStream in ) { cin = new ASCIIInputStream( in ); } // Read a command from client, translate to command object public SPOP_Command readSPOP_Command() { String fromClient = cin.readLine(); SPOP_Command commandFromClient; commandFromClient = SPOP_Command.fromString( fromClient ); return commandFromClient ; } // Read a response from server, translate to command object public SPOP_Response readSPOP_Response() { // Like readSPOP_Command but harder } }
public class SPOPState { public SPOPState USER( SPOP_Command clientRequest, SPOP_Response serverResponse ) { serverResponse = new SPOP_Response( "-ERR" ); return new Invalid(); } public SPOPState PASS( SPOP_Command clientRequest, SPOP_Response serverResponse ) { serverResponse = new SPOP_Response( "-ERR" ); return new Invalid(); } public SPOPState LIST( SPOP_Command clientRequest, SPOP_Response serverResponse ) { serverResponse = new SPOP_Response( "-ERR" ); return new Invalid(); } public SPOPState RETR( SPOP_Command clientRequest, SPOP_Response serverResponse ) { serverResponse = new SPOP_Response( "-ERR" ); return new Invalid(); } public SPOPState QUIT( SPOP_Command clientRequest, SPOP_Response serverResponse ){ serverResponse = new SPOP_Response( "-ERR" ); return new Invalid(); } }
public class NoAuth extends SPOPState { public SPOPState USER( SPOP_Command clientRequest, SPOP_Response serverResponse ) { serverResponse = new SPOP_Response( "+OK" ); String userName = clientRequest.getData(); return new HaveUser( userName ); } }
public class HaveUser extends SPOPState { protected String userName; public HaveUser( String name ) { userName = name; } public SPOPState PASS( SPOP_Command clientRequest, SPOP_Response serverResponse ) { String password = clientRequest.getData(); put some code here that verifies that userName and password form a valid login if valid login then { serverResponse = new SPOP_Response( "+OK" ); return new Process( ); } else { serverResponse = new SPOP_Response( "+ERR" ); return new Invalid( ); } } }