scp-app

git clone git://git.codymlewis.com/scp-app.git
Log | Files | Refs | LICENSE

ChatClient.java (4582B)


      1 import java.math.BigInteger;
      2 import java.io.BufferedReader;
      3 import java.io.PrintWriter;
      4 import java.io.InputStreamReader;
      5 import java.io.IOException;
      6 import java.net.Socket;
      7 import java.net.InetAddress;
      8 import java.net.UnknownHostException;
      9 /**
     10  * ChatClient.java
     11  * A socket based full duplex chat client
     12  *
     13  * @author Cody Lewis
     14  * @since 2018-08-10
     15  */
     16 public class ChatClient extends Chat {
     17     public static final long serialVersionUID = 1L;
     18     public ChatClient(String title) { super(title); }
     19     /**
     20      * The main thread
     21      * @param args command line arguments
     22      */
     23     public static void main(String args[]) {
     24         ChatClient cc = new ChatClient("SCP Client");
     25         int exitVal = cc.run(args);
     26         System.exit(exitVal);
     27     }
     28     /**
     29      * Main flow of the program
     30      * @param args arguments sent in with the program
     31      * @return an end status int
     32      */
     33     public int run(String args[]) {
     34         try {
     35             address = args.length > 0 ? InetAddress.getByName(args[0]) : InetAddress.getLocalHost();
     36             port = args.length > 1 ? Integer.parseInt(args[1]) : 3400;
     37             msgArea.append(String.format("Connecting to %s:%d\n", address.getHostAddress(), port));
     38             connectToServer();
     39             msgArea.append("Connected to server\n");
     40             msgArea.append("Exchanging keys with the server\n");
     41             keyExchange();
     42             username = args.length > 2 ? args[2] : "Client";
     43             otherUsername = "Server";
     44             SCPConnect();
     45             msgArea.append("Connected to SCP\n");
     46             while(!disconnect) {
     47                 messageLoop();
     48                 while(recvMsg.isAlive() || !disconnect);
     49             }
     50             return 0;
     51         } catch(SCPException SCPe) {
     52             System.err.println("Error: " + SCPe.getMessage());
     53             return errorCodes.SCPERROR.value();
     54         } catch(UnknownHostException uhe) {
     55             System.err.println("Error: " + uhe.getMessage());
     56             return errorCodes.UNKNOWNHOSTERROR.value();
     57         } catch(IOException ioe) {
     58             System.err.println("Error: " + ioe.getMessage());
     59             return errorCodes.IOERROR.value();
     60         } catch(NullPointerException npe) {
     61             System.err.println("\nError: unexpected cutoff from Server, ending program");
     62             return errorCodes.NULLERROR.value();
     63         }
     64     }
     65     /**
     66      * Connect to the server
     67      * @param hostName the name of the server
     68      * @param port the port number the server is running on
     69      * @return true on successful connection
     70      */
     71     private boolean connectToServer() throws UnknownHostException, IOException {
     72         cliSocket = new Socket(address.getHostAddress(), port);
     73         out = new PrintWriter(cliSocket.getOutputStream(), true);
     74         in = new BufferedReader(new InputStreamReader(cliSocket.getInputStream()));
     75         return true;
     76     }
     77     /**
     78      * perform a diffie-hellman key exchange
     79      * @return true on completion
     80      */
     81     private boolean keyExchange() throws IOException {
     82         BigInteger prime = DH.genPrime(16);
     83         out.println(prime); // send prime to server
     84         BigInteger priKey = DH.genPrivateKey(prime);
     85         BigInteger pubKey = DH.genPublicKey(priKey, prime);
     86         out.println(pubKey);
     87         sessionKey = DH.genSessionKey(new BigInteger(in.readLine()), priKey, prime);
     88         return true;
     89     }
     90     /**
     91      * Send the SCP connection packet
     92      * @param hostName the name of the server
     93      * @param port the port number the server is running on
     94      * @param username client specified username
     95      * @return true on packet send
     96      */
     97     private boolean SCPConnect() throws SCPException, IOException {
     98         String connectionString = SCP.connect(username, address.getHostAddress(), port);
     99         out.println(connectionString);
    100         if(SCPDecide()) {
    101             SCPAcknowledge();
    102             return true;
    103         }
    104         return false;
    105     }
    106     /**
    107      * Find out whether the server accepted or rejected by the server
    108      * @return true if accepted, false if rejected
    109      */
    110     private boolean SCPDecide() throws SCPException, IOException {
    111         String inLine, packet = "";
    112         while((inLine = in.readLine()).compareTo("SCP END") != 0) {
    113             packet += inLine + "\n";
    114         }
    115         return SCP.parseAccept(packet, username, address.getHostAddress(), port);
    116     }
    117     /**
    118      * Send a acknowledge SCP packet to the server
    119      */
    120     private void SCPAcknowledge() {
    121         out.println(SCP.acknowledge(username, address.getHostAddress(), port));
    122     }
    123 }