Advertisement
Guest User

Untitled

a guest
Jun 24th, 2017
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.77 KB | None | 0 0
  1. import java.io.IOException;
  2. import java.io.ObjectInputStream;
  3. import java.io.ObjectOutputStream;
  4. import java.net.ServerSocket;
  5. import java.net.Socket;
  6. import java.net.UnknownHostException;
  7. import java.util.Random;
  8.  
  9.  
  10. public class SocketConnection {
  11.  
  12.     //Instance variables
  13.     private volatile Socket socket;
  14.     private ServerSocket serverSocket;
  15.     private Set2DArray clients = new Set2DArray(5,2);
  16.     private Thread server;
  17.     private Thread send;
  18.     private Thread sendAll;
  19.     private Thread connect;
  20.     private SpawnSendSpecific spawnSpecific;
  21.     private volatile Object[] control = new Object[3];
  22.     private volatile boolean spawn = false;
  23.     private volatile boolean alive = true;
  24.     private static Object threadLock = new Object();
  25.  
  26.     /**
  27.      * Server is used to initialize a thread daemon that will spawn new threads as clients connect.
  28.      * @param int port
  29.      */
  30.     public void server(int port) {
  31.         Runnable serverThread = new ServerThread(port);
  32.         server = new Thread(serverThread, "serverDaemon");
  33.         server.setDaemon(true);
  34.         server.start();
  35.     }
  36.  
  37.     /**
  38.      * ServerThread is the daemon thread that infinitely loops waiting for clients to connect.
  39.      * @author xPhilosx
  40.      * @param int port
  41.      */
  42.     private class ServerThread implements Runnable {
  43.         private int port;
  44.  
  45.         public ServerThread(int port) {
  46.             this.port = port;
  47.         }
  48.  
  49.         /**
  50.          * Accepts new clients and spawns a unique thread to handle traffic.
  51.          */
  52.         @Override
  53.         public void run() {
  54.             try {
  55.                 serverSocket = new ServerSocket(port);
  56.                 while (alive) {
  57.                     //Accept the new connection
  58.                     Socket socket = serverSocket.accept();
  59.  
  60.                     //Creates a unique player ID for each client.
  61.                     String pid = generatePid();
  62.                     clients.add(socket, pid);
  63.  
  64.                     //Spawn a unique thread for each client.
  65.                     Runnable clientThread = new ClientThread(socket, pid);
  66.                     Thread thread = new Thread(clientThread, "client-" + clients.size());
  67.                     thread.start();
  68.                 }
  69.             } catch (IOException e) {
  70.                 e.printStackTrace();
  71.             }
  72.         }
  73.     }
  74.  
  75.     /**
  76.      * Generates a random player ID (PID)
  77.      * @return
  78.      */
  79.     private String generatePid() {
  80.         Random r = new Random();
  81.         String token = Long.toString(Math.abs(r.nextLong()), 36);
  82.         return token;
  83.     }
  84.  
  85.     /**
  86.      * A unique thread for each individual client that connects to the server.
  87.      * @author xPhilosx
  88.      *
  89.      */
  90.     private class ClientThread implements Runnable {
  91.  
  92.         private Socket s;
  93.         private String pid;
  94.  
  95.         public ClientThread(Socket s, String pid) {
  96.             this.s = s;
  97.             this.pid = pid;
  98.         }
  99.  
  100.         /**
  101.          * Sends the initial connection information and then infinitely loops waiting for traffic
  102.          */
  103.         @Override
  104.         public void run() {
  105.             //Send initial handshake information: the PID, ... //TODO: Finish handshake info
  106.             //send(s, pid);
  107.             System.out.println("Total clients: " + clients.size());
  108.             System.out.println(s);
  109.             //An infinitely loop to read traffic from the client.
  110.             while (alive) {
  111.                 try {
  112.                     ObjectInputStream inStream = new ObjectInputStream(s.getInputStream());
  113.                     Object readStream = inStream.readObject();
  114.                     //TODO: add some kind of behavior based on readStream's value (instanceof).
  115.                 } catch (IOException e) {
  116.                     //e.printStackTrace();
  117.                 }
  118.                 catch (ClassNotFoundException e) {
  119.                     e.printStackTrace();
  120.                 }
  121.             }
  122.         }
  123.     }
  124.  
  125.     /**
  126.      * Starts a daemon thread to spawn multiple threads to write objects across the network.
  127.      * @param Socket s
  128.      * @param Object o
  129.      */
  130.     public void send(Socket s, Object o) {
  131.         //Checks to see if the daemon is started, if its started then it just issues control commands.
  132.         if (send == null || !send.isAlive()) {
  133.             spawnSpecific = new SpawnSendSpecific(s, o);
  134.             Runnable spawnSendSpecific = spawnSpecific;
  135.             send = new Thread(spawnSendSpecific, "sendDaemon");
  136.             send.setDaemon(true);
  137.             send.start();
  138.         }
  139.         else {
  140.             setControl(true, s, o);
  141.         }
  142.     }
  143.  
  144.     private synchronized void setControl(Boolean spawn, Socket s, Object o) {
  145.         this.spawn = spawn;
  146.         control[0] = s;
  147.         control[2] = o;
  148.     }
  149.  
  150.     private synchronized Object[] getControl() {
  151.         return control;
  152.     }
  153.  
  154.     public class SpawnSendSpecific implements Runnable { //TODO: fix with volatile variables
  155.  
  156.         private Object o;
  157.         private Socket s;
  158.  
  159.         public SpawnSendSpecific(Socket s, Object o) {
  160.             this.o = o;
  161.             this.s = s;
  162.         }
  163.  
  164.         public void run() {
  165.             waitCommand();
  166.         }
  167.  
  168.         /**
  169.          * Infinite loop: When spawn is true then it spawns a new thread to write data.
  170.          */
  171.         private void waitCommand() {
  172.             //Spawn the initial thread to write an object.
  173.             spawnThread();
  174.  
  175.             //Infinitely loop waiting to spawn more threads.
  176.             while (alive) {
  177.                 if (spawn) {
  178.                     Object[] control = getControl();
  179.                     s = (Socket) control[0];
  180.                     o = control[1];
  181.                     spawnThread();
  182.                     setControl(false, null, null);
  183.                 }
  184.             }
  185.         }
  186.  
  187.         /**
  188.          * Starts a new thread to write an object to a client.
  189.          */
  190.         public void spawnThread() {
  191.             Runnable sendSpecific = new SendSpecific(s, o);
  192.             Thread send = new Thread(sendSpecific, "send");
  193.             send.start();
  194.         }
  195.     }
  196.  
  197.     /**
  198.      * Thread that writes an object across the network to a unique client.
  199.      * @author xPhilosx
  200.      * @param Socket s
  201.      * @param Object o
  202.      */
  203.     private class SendSpecific implements Runnable {
  204.         private Object o;
  205.         private Socket s;
  206.  
  207.         public SendSpecific(Socket s, Object o) {
  208.             this.o = o;
  209.             this.s = s;
  210.         }
  211.  
  212.         public void run() {
  213.             System.out.println("tried");
  214.             try {
  215.                 ObjectOutputStream outStream = new ObjectOutputStream(s.getOutputStream());
  216.                 outStream.writeObject(o);
  217.                 outStream.flush();
  218.                 outStream.reset();
  219.             } catch (IOException e) {
  220.                 e.printStackTrace();
  221.             }
  222.         }
  223.     }
  224.  
  225.     /**
  226.      * Starts a thread to write an object to every client.
  227.      * @param Object o
  228.      */
  229.     public void send(Object o) {
  230.         Runnable sendMany = new SendMany(o);
  231.         sendAll = new Thread(sendMany);
  232.         sendAll.start();
  233.     }
  234.  
  235.     /**
  236.      * A thread that calls send() for each client in the Set2DArray clients.
  237.      * @author xPhilosx
  238.      *
  239.      */
  240.     private class SendMany implements Runnable {
  241.         private Object o;
  242.  
  243.         public SendMany(Object o) {
  244.             this.o = o;
  245.         }
  246.  
  247.         /**
  248.          * Loops through all the clients and will call send() (spawning a new thread) to
  249.          * write an object across the network to each client.
  250.          */
  251.         public void run() {
  252.             System.out.println("total to send: " + clients.size());
  253.             for (int i = 0; i < clients.size(); i++) {
  254.                 System.out.println("check");
  255.                 Socket s = (Socket) clients.get(i);
  256.                 send(s, o);
  257.             }
  258.         }
  259.     }
  260.  
  261.     /**
  262.      * Starts a thread to connect and listen to a server.
  263.      * @param String IP
  264.      * @param int port
  265.      */
  266.     public void connect(String IP, int port) {
  267.         //Kills the current connection if one is alive.
  268.         if (connect != null && connect.isAlive())
  269.             close();
  270.  
  271.         //Starts the thread.
  272.         Runnable connectTo = new ConnectTo(IP, port);
  273.         connect = new Thread(connectTo, "self");
  274.         connect.start();
  275.  
  276.     }
  277.  
  278.     /**
  279.      * A thread that connects to a server specified by IP and port.  Sends initial handshake,
  280.      * and creates an infinite loop that will listen for traffic and respond accordingly.
  281.      * @author xPhilosx
  282.      *
  283.      */
  284.     private class ConnectTo implements Runnable {
  285.         private String IP;
  286.         private int port;
  287.  
  288.         public ConnectTo(String IP, int port) {
  289.             this.IP = IP;
  290.             this.port = port;
  291.         }
  292.  
  293.         public void run() {
  294.             try {
  295.                 socket = new Socket(IP, port);
  296.                 while (alive) {
  297.                     //Sets up the input stream
  298.                     System.out.println("waiting, faithfully");
  299.                     ObjectInputStream inStream = new ObjectInputStream(socket.getInputStream());
  300.                     Object readStream = inStream.readObject();
  301.  
  302.                     //Decides how to process the received object.
  303.                     if (readStream instanceof String)
  304.                         System.out.println(readStream);
  305.                 }
  306.             } catch (UnknownHostException e) {
  307.             } catch (IOException e) {
  308.             } catch (ClassNotFoundException e) {
  309.                 //e.printStackTrace();
  310.             }
  311.         }
  312.     }
  313.  
  314.     /**
  315.      * Closes out all the threads and closes all open sockets.  This will kill all the clients.
  316.      * @return
  317.      * @throws IOException
  318.      */
  319.  
  320.     public void close() {
  321.         alive = false;
  322.         //Shuts down each open socket and then closes the corresponding thread.
  323.         try {
  324.             //Closes the client socket on the *client side*
  325.             if (socket != null && socket.isConnected()) {
  326.                 socket.close();
  327.                 connect = null;
  328.             }
  329.             //Loops through all the client sockets on the *server side* and shuts them down.
  330.             for (int i = 0; i < clients.size(); i++) {
  331.                 Socket temp = (Socket) clients.get(i);
  332.                 if (temp.isConnected())
  333.                     temp.close();
  334.             }
  335.             //Closes the server socket and exits the server daemon thread.
  336.             if (serverSocket != null && serverSocket.isClosed()) {
  337.                 serverSocket.close();
  338.                 server = null;
  339.             }
  340.         } catch (IOException e) {
  341.         }
  342.     }
  343.  
  344.     /**
  345.      * Returns the client list
  346.      * @return
  347.      */
  348.     public Set2DArray getClients() {
  349.         return clients;
  350.     }
  351. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement