Nzen avatar Nzen committed 2c36320

Just in case, also doesn't work

"What we have here is a failure to communicate." I had hoped that Timon &
Jonathan would each take the full functionality of server or client. Timon
stopped at a strange handshake for both (that bypassed PhysicalLayer for
some reason). Jonathan hasn't responded since he called me 'yesterday.'
So, I spent midnight oil finishing the rest.

Unfortunately, I seem to have made some grave error. On line 83 of server,
the string assignment reports a null pointer. (Same problem for 75 &
subsequent I'll bet, but I cut 75 out.) I have no idea why. TestPhysical
reports specialOut( ) provides the encoded strings correctly.
Unfortunately, my judgment is compromised. So, I put this on a different
branch in case Jonathan finishes one of those classes. If not, this needs
to be made to work.

Operation: on separate threads, java Server 50000; java Client 127.0.0.1
50000. Theoretically, the server & client will start annnouncing their
view of the handshake. Server is geared to fail to connect sometimes.
Client then prompts for x<20 messages less than 16 chars each. Server will
echo the message as all caps. (Arbitrary decision, I'm inclined to show
the bit strings too, but it has to work first.)

It's really late, so I will wake late and then go to an appointment at 12,
perhaps until 2. I will arrive to class. If you feel that Timothy's
implementation better satisfies the spec, you need to add communication
functionality.
will wake late

Comments (0)

Files changed (4)

 import java.net.*;
 import java.io.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import java.util.Scanner;
+	/*	PhysicalLayer API
+	
+	String specialOut( Comm exe )
+	String encode( String message )
+	Comm whichSpecialInput( String bitString )
+	String link.decode(Bits);
+	*/
+
+// command line > java Client 127.0.0.1 (port#, but unnecessary)
 
 public class Client
 {
-    private static boolean ackValue;
-	private static boolean ackSent;
-	private static final int ACKSIZE = 13;	//Size of the ACK buffer
+    private static boolean connected;
+	private static final int BUFSIZE = 32;	//Size of the ACK buffer
+	private static PhysicalLayer ethernet;
+	
 	public static void main( String[] args ) throws IOException
 	{
-		ackValue = false;
-		ackSent = false;
+		ethernet = new PhysicalLayer( );
 		testArgs( args.length );
 		String server = args[ 0 ];       // Server name/IP	
 		int servPort = ( args.length == 2 ) ? Integer.parseInt(args[1]) : 7;
 		
-		//set up
-		byte[] RequestData = "Client Requesting Service".getBytes();
-		
-		System.out.println("Will now attempt to connect to server at " + server + ", Port "  + servPort  );
+		System.out.println("Connecting to server at " + server + ", Port "  + servPort  );
 		
-		
-		//Connect to the server
-		Socket socket = new Socket(server, servPort);
-		System.out.println("Connected to server");
-		
-
-		int count = 0;
-		while(count < 10){
-			try {
-				Thread.sleep(3000);
-			} catch (Exception ex) {}
-			//wait till confirmation received from server then do handle session for encoding
-			if(ackValue){
-				handleSession( socket );
-			}
-			else if(!ackSent){
-				//Begin handshake
-					handShake ( socket, RequestData );
-					ackSent = true;
-				}
-			count++;
-			if(count == 10){
-			//user idleness, depends on how it should be implemented
-				System.out.println("\nTime taken too long for server to respond, sending another handshake");
-				count = 0;
-				ackSent = false;
-			}
-		}
-		socket.close();
+		Socket serverConn = new Socket(server, servPort);
+		handleSession( serverConn );
+		serverConn.close();
 		
 	}
 	static void testArgs( int numArgs ) throws IOException
 			throw new IllegalArgumentException( "Required parameter(s): ServerName/IP (Port#)" );
 	}
 	
-	static void handShake( Socket serverConn, byte[] request ) throws IOException
+	static void handleSession( Socket serverConn ) throws IOException
 	{
-		String acknowledgement = "Ready To Help";
-		//server response to receive
-		byte[] response = new byte[ACKSIZE];
-		//Expect Ready to help string response from server
-	
-		//System.out.println("Attempting Handshake");
-		InputStream in = serverConn.getInputStream();
-		OutputStream out = serverConn.getOutputStream();
-		
-		//Send confirmation data to server
-		out.write(request);
-		
-		//wait for confirmation from Server
-		int totalBytesRcvd = 0;
-		int bytesRcvd;
-		
-		in.read( response );
-		String responseString = new String(response);
-		if(responseString.equals(acknowledgement)){
-			ackValue = true;
+		boolean finished = false;
+		connected = false;	// return satisfied?
+		int count = 0;
+		while(count < 10 && !finished ){
+			try {
+				Thread.sleep(1000);
+			} catch (Exception ex) {}
+			if( connected ){
+				System.out.println("Connected to server");
+				finished = communicate( serverConn );
+			}
+			else
+				handShake ( serverConn );
+			count++;
 		}
-		/*
-		while(totalBytesRcvd < acknowledgement.length){
-			if((bytesRcvd = in.read(response, totalBytesRcvd, response.length - totalBytesRcvd)) == -1)
-				throw new SocketException("Connection closed prematurely");
-                        
-			totalBytesRcvd += bytesRcvd;
-		}*/
-		
-	}
-	
-	
-	static void handleSession( Socket serverConn  ) throws IOException
-	{
-		System.out.println("Works, Continue messaging from here");
-		serverConn.close();
-		/*
-		InputStream in = serverConn.getInputStream();
-		OutputStream out = serverConn.getOutputStream();
-		
-		
-
-		byte[] byteBuffer = "basic I/O".getBytes(); // REPLACE
-		out.write( byteBuffer );
-
-		while ( in.read( byteBuffer ) != -1 )
-			System.out.println( "Received: " + new String( byteBuffer ) ); // REPLACE
-			*/
+		System.out.println("\nTime out for server response, please check IP & restart");
 	}
 	
-	/*		( potential algorithm )
+	/*		Handshake
 	 * open socket
 	 * if ( don't receive idle )
 	 *  	 sleep 1 sec
 	 * 	another message?
 	 * close connection
 	 */
+	static void handShake( Socket serverConn ) throws IOException
+	{
+		byte[] response = new byte[BUFSIZE];
+
+		InputStream in = serverConn.getInputStream();
+		OutputStream out = serverConn.getOutputStream();
+		
+		in.read( response );		
+		// listen for idle server
+		if ( ethernet.whichSpecialInput( ethernet.decode( new String( response ) ) ) != Comm.idle )
+		{
+			System.out.println( "Server busy or connection lost" );
+			return; // & sleep
+		}
+		else
+		{
+			System.out.println( "Found idle server, requesting connection" );
+			// ask to connect
+			out.write( ethernet.specialOut( Comm.startAsk ).getBytes( ) );
+			in.read( response );
+			if ( ethernet.whichSpecialInput( ethernet.decode( new String( response ) ) ) != Comm.startAck )
+			{
+				System.out.println( "Connection lost" );
+				return; // connection lost; sleep
+			}
+			else	// ready to write message
+			{
+				System.out.println( "StartAck received, beginning message" );
+				connected = true;
+			}
+		}
+	}
+	
+	static boolean communicate( Socket serverConn ) throws IOException
+	{
+		String reply;
+		boolean unfinished = true;
+		byte[ ] byteBuffer = new byte[ BUFSIZE ];
+		InputStream in = serverConn.getInputStream();
+		OutputStream out = serverConn.getOutputStream();
+		while( unfinished )
+		{
+			byteBuffer = ethernet.encode( userMessage( ) ).getBytes( );
+			out.write( byteBuffer );
+			in.read( byteBuffer );
+			reply = ethernet.decodeCompletely( new String( byteBuffer ) );
+			// print response
+			System.out.print( "Server:\t" + reply );
+			unfinished = messageIncomplete( );
+		}
+		out.write( ethernet.specialOut( Comm.end ).getBytes( ) );
+		return true; // finished
+	}
+	
+	static String userMessage( )
+	{
+		String message;
+		boolean invalid = true;
+		Scanner uInput = new Scanner( System.in );
+		while ( invalid )
+		{
+			System.out.print( " -- " );
+			message = uInput.nextLine( );
+			if ( message.length( ) >= BUFSIZE / 2 )
+				System.out.println( "Message too long. Please twitterfy to 15 chars." );
+			else
+				return message;
+		}
+		return "unreachable";
+	}
+	
+	static boolean messageIncomplete( )
+	{
+		Scanner uInput = new Scanner( System.in );
+		String response;
+		while ( true )
+		{
+			System.out.print( "Finished? ( y/n ) -- " );
+			response = uInput.nextLine( );
+			response.toLowerCase( );
+			if ( response.startsWith( "y" ) ) // slightly brittle
+				return false;
+			else if ( response.startsWith( "n" ) ) // but sufficient
+				return true;
+			else
+				System.out.println( "Please respond either yes or no." );
+		}
+	}
 }

PhysicalLayer.java

 		}
 	}
 	
-	// message to bits to encoding switch, return new bits
+	// message to bits to encoding switch; return new bits
 	String encode( String message )
 	{
 		toBitBuff( message );
 			return Comm.NULL; // This wasn't a command, move to decode
 	}
 	
+	// only turns it into decimal bits
 	String decode( String fourB5B )
 	{
 		//4B to string
            text.append( decoder(str[a]) );
 		   return text.toString( );
 	}
+	
+	// turns encoded bytes into decoded text
+	String decodeCompletely( String bits )
+	{
+		String fourB5B = fiveB4B( bits );
+		//4B to string
+        String[] str=splitInParts(fourB5B,8);
+        StringBuilder text= new StringBuilder( );
+     
+        for(int a=0;a<str.length;a++)
+           text.append( decoder(str[a]) );
+		   return text.toString( );
+	}
   	
 	public String fiveB4B(String textE)
 	{
 import java.net.*;
 import java.io.*;
+import java.util.Random;
+	/*	PhysicalLayer API
+	
+	String specialOut( Comm exe )
+	String encode( String message )
+	Comm whichSpecialInput( String bitString )
+	String link.decode(Bits);
+	*/
+
+// command line > java Server 50000 (or OS appropriate ephemeral port)
 
 public class Server
 {
 	private static final int BUFSIZE = 32;   // Size of receive buffer
-	private static final int ACKSIZE = 25;	//Size of the ACK buffer
 	private static byte[] byteBuffer;
-	private static boolean ackValue;
+	private static boolean connected;
+	private static PhysicalLayer ethernet;
 	
 	public static void main( String[] args ) throws IOException
 	{
 		int servPort = Integer.parseInt(args[0]);
 		ServerSocket servSock = new ServerSocket(servPort);
 		byteBuffer = new byte[ BUFSIZE ];
+		System.out.println("Server is now ready to receive clients at port " + servPort);
 		
-		ackValue = false;//initial setting for the hand
-		
-		
-		System.out.println("Server is now ready to receive client at port " + servPort);
-		//Setup of the sockets, in, and out
 		Socket clntSock = servSock.accept();
 		SocketAddress clientAddress = clntSock.getRemoteSocketAddress();
-		while( true ){
-			//Setup of the sockets, in, and out
-			//Socket clntSock = servSock.accept();
-			//SocketAddress clientAddress = clntSock.getRemoteSocketAddress();
-			System.out.println("Handling client at " + clientAddress);
-
-			if(ackValue)
-			{
-				handleClients( servSock, clntSock );
-				break;
-				}
-			else
-			
-				handShake( servSock, clntSock );
-          }
+		System.out.println("Sensed client at " + clientAddress);
+		handleSession( clntSock );
 		servSock.close();
      }
 	
 			throw new IllegalArgumentException( "Only parameter: Port#" );
 	}
 	
-	static void handShake( ServerSocket servSock, Socket clntSock) throws IOException
+	static void handleSession( Socket clntSock) throws IOException
 	{
-		System.out.println("Checking for handshake");
-		String expectedHand = "Client Requesting Service";
-		byte[] acknowledgement = "Ready To Help".getBytes(); 
-		byte[] receiveHand = new byte[ACKSIZE];
-
+		int tries = 20;
+		connected = false;
+		boolean success = false;
+		while( tries >= 0 ){
+			if( connected )
+			{
+				communicate( clntSock );
+				return;
+			}
+			else
+			{
+				success = handShake( clntSock );
+				if ( !success )
+				{
+					try
+					{	Thread.sleep(1000); }
+					catch (Exception ex) {}
+				}
+			}
+			tries--;
+        }
+	}
+	
+	static boolean handShake( Socket clntSock ) throws IOException
+	{
+		String nn;
+		byte[] response = new byte[BUFSIZE];
 		InputStream in = clntSock.getInputStream();
 		OutputStream out = clntSock.getOutputStream();
-		
-		while ( true )
+		if ( false )//badState( ) )
 		{
-			in.read( receiveHand );
-			String received = new String(receiveHand);
-			String ack = new String(acknowledgement);
-			System.out.println(ack.length());
-			if(received.equals(expectedHand))
+			System.out.println( "Server busy" );
+			byteBuffer = ethernet.specialOut( Comm.quiet ).getBytes( );
+			out.write( byteBuffer );
+			return false; // no success
+		}
+		else
+		{
+			System.out.println( "Server idle" );
+			nn = ethernet.specialOut( Comm.idle );
+			byteBuffer = nn.getBytes( );
+			out.write( byteBuffer );
+			in.read( response );
+			if ( ethernet.whichSpecialInput( new String( response ) ) != Comm.startAsk )
 			{
-				out.write( acknowledgement ); // echoing action // REPLACE
-				ackValue = true;
-				break;
+				System.out.println( "Ambiguous client request, closing" ); // extremely unlikely
+				return false; // no success
 			}
-			else{
-				System.out.println("Client request string rejected");
+			else if ( badState(  ) )
+			{
+				System.out.println( "Line quiet: connection lost" );
+				return false; // no success
+			}
+			else
+			{
+				System.out.println( "Start request acknowledged" );
+				return true; // woo!
 			}
 		}
-		
-		System.out.println("Received: " + new String(receiveHand));
 	}
 	
-	static void handleClients( ServerSocket servSock,  Socket clnt ) throws IOException
+	static boolean badState( )
 	{
-		System.out.println("Continue Messaging from here");
-		servSock.close();
-		//InputStream in = clntSock.getInputStream();
-		//OutputStream out = clntSock.getOutputStream();
-		
-		//Encoding work will continue here.
-		/*
-		while ( in.read( byteBuffer ) != -1 )
+		Random gen = new Random( 42 );
+		return gen.nextBoolean( );
+	}
+	static void communicate( Socket clntConn ) throws IOException // FIX, THIS IS CLIENT CODE 4 25, 2:39am
+	{
+		String reply;
+		Comm flag;
+		byteBuffer = new byte[ BUFSIZE ];
+		InputStream in = clntConn.getInputStream();
+		OutputStream out = clntConn.getOutputStream();
+		while( true )
 		{
-			for ( byte nn : byteBuffer )
-				System.out.print( (char) nn ); // printing to screen // REPLACE
-			out.write( byteBuffer ); // echoing action // REPLACE
+			in.read( byteBuffer );
+			flag = ethernet.whichSpecialInput( ethernet.decode( new String( byteBuffer ) ) );
+			if ( flag == Comm.end )
+			{
+				System.out.println( "Communication complete, closing socket" );
+				return;
+			}
+			else if ( flag == Comm.NULL ) // ie text
+			{
+				reply = ethernet.decodeCompletely( new String( byteBuffer ) );
+				System.out.print( "Client:\t" );
+				reply.toUpperCase( );
+				byteBuffer = ethernet.encode( reply ).getBytes( );
+				out.write( byteBuffer );
+			}
+			else
+				System.out.println( "Ambiguous client request\t" ); // unreachable?
 		}
-                clnt.close();
-				*/
-		
 	}
-	
-	/*		( potential algorithm )
-	 *  socket.accept connection
-	 *  	[ assuming server 'reports' state rather than listening by default ]
-	 *  decide state
-	 *  	quiet : sleep 1 sec, return
-	 *  	idle : read
-	 *  	- if ( received ask )
-	 *  	- decide connection state
-	 *  		quiet : sleep 1 sec, return
-	 *  		acknowledge : read message; (echo? react? print?)
-	 *  		if ( received end )
-	 *  		- close connection
-	 */
 }

TestPhysical.java

 	
 	static String testOutput( PhysicalLayer link )
 	{
+		testCommOut( link );
 		String output;
 		String message = "/>M\\kz!0HY";
 		System.out.println( "Testing />M\\kz!0HY" );
 		System.out.println( "in hex: 2F 3E 4D 5C 6B 7A 21 30 48 59" );
 		output = link.encode( message );
 		System.out.printf( "Encoded bits: %s\n", output );
-		// Produces codes matching 2F 3E 4D 5C 6B 7A 31 30 48 59
+		// Produces codes matching 2F 3E 4D 5C 6B 7A 21 30 48 59, hence operation vetted
 		return output;
 	}
 	
+	static void testCommOut( PhysicalLayer link )
+	{
+		Comm[] bla = { Comm.idle, Comm.end, Comm.NULL };
+		for ( Comm nn : bla )
+			System.out.println( link.specialOut( nn ) );
+	}
+	
 	static void pretestInput( PhysicalLayer link )
 	{
 		System.out.println( "Should print quiet, ack, end, idle, null, ask" );
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.