Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.net.UnknownHostException;
- import java.util.Random;
- public class SocketConnection {
- //Instance variables
- private volatile Socket socket;
- private ServerSocket serverSocket;
- private Set2DArray clients = new Set2DArray(5,2);
- private Thread server;
- private Thread send;
- private Thread sendAll;
- private Thread connect;
- private SpawnSendSpecific spawnSpecific;
- private volatile Object[] control = new Object[3];
- private volatile boolean spawn = false;
- private volatile boolean alive = true;
- private static Object threadLock = new Object();
- /**
- * Server is used to initialize a thread daemon that will spawn new threads as clients connect.
- * @param int port
- */
- public void server(int port) {
- Runnable serverThread = new ServerThread(port);
- server = new Thread(serverThread, "serverDaemon");
- server.setDaemon(true);
- server.start();
- }
- /**
- * ServerThread is the daemon thread that infinitely loops waiting for clients to connect.
- * @author xPhilosx
- * @param int port
- */
- private class ServerThread implements Runnable {
- private int port;
- public ServerThread(int port) {
- this.port = port;
- }
- /**
- * Accepts new clients and spawns a unique thread to handle traffic.
- */
- @Override
- public void run() {
- try {
- serverSocket = new ServerSocket(port);
- while (alive) {
- //Accept the new connection
- Socket socket = serverSocket.accept();
- //Creates a unique player ID for each client.
- String pid = generatePid();
- clients.add(socket, pid);
- //Spawn a unique thread for each client.
- Runnable clientThread = new ClientThread(socket, pid);
- Thread thread = new Thread(clientThread, "client-" + clients.size());
- thread.start();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * Generates a random player ID (PID)
- * @return
- */
- private String generatePid() {
- Random r = new Random();
- String token = Long.toString(Math.abs(r.nextLong()), 36);
- return token;
- }
- /**
- * A unique thread for each individual client that connects to the server.
- * @author xPhilosx
- *
- */
- private class ClientThread implements Runnable {
- private Socket s;
- private String pid;
- public ClientThread(Socket s, String pid) {
- this.s = s;
- this.pid = pid;
- }
- /**
- * Sends the initial connection information and then infinitely loops waiting for traffic
- */
- @Override
- public void run() {
- //Send initial handshake information: the PID, ... //TODO: Finish handshake info
- //send(s, pid);
- System.out.println("Total clients: " + clients.size());
- System.out.println(s);
- //An infinitely loop to read traffic from the client.
- while (alive) {
- try {
- ObjectInputStream inStream = new ObjectInputStream(s.getInputStream());
- Object readStream = inStream.readObject();
- //TODO: add some kind of behavior based on readStream's value (instanceof).
- } catch (IOException e) {
- //e.printStackTrace();
- }
- catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
- }
- }
- /**
- * Starts a daemon thread to spawn multiple threads to write objects across the network.
- * @param Socket s
- * @param Object o
- */
- public void send(Socket s, Object o) {
- //Checks to see if the daemon is started, if its started then it just issues control commands.
- if (send == null || !send.isAlive()) {
- spawnSpecific = new SpawnSendSpecific(s, o);
- Runnable spawnSendSpecific = spawnSpecific;
- send = new Thread(spawnSendSpecific, "sendDaemon");
- send.setDaemon(true);
- send.start();
- }
- else {
- setControl(true, s, o);
- }
- }
- private synchronized void setControl(Boolean spawn, Socket s, Object o) {
- this.spawn = spawn;
- control[0] = s;
- control[2] = o;
- }
- private synchronized Object[] getControl() {
- return control;
- }
- public class SpawnSendSpecific implements Runnable { //TODO: fix with volatile variables
- private Object o;
- private Socket s;
- public SpawnSendSpecific(Socket s, Object o) {
- this.o = o;
- this.s = s;
- }
- public void run() {
- waitCommand();
- }
- /**
- * Infinite loop: When spawn is true then it spawns a new thread to write data.
- */
- private void waitCommand() {
- //Spawn the initial thread to write an object.
- spawnThread();
- //Infinitely loop waiting to spawn more threads.
- while (alive) {
- if (spawn) {
- Object[] control = getControl();
- s = (Socket) control[0];
- o = control[1];
- spawnThread();
- setControl(false, null, null);
- }
- }
- }
- /**
- * Starts a new thread to write an object to a client.
- */
- public void spawnThread() {
- Runnable sendSpecific = new SendSpecific(s, o);
- Thread send = new Thread(sendSpecific, "send");
- send.start();
- }
- }
- /**
- * Thread that writes an object across the network to a unique client.
- * @author xPhilosx
- * @param Socket s
- * @param Object o
- */
- private class SendSpecific implements Runnable {
- private Object o;
- private Socket s;
- public SendSpecific(Socket s, Object o) {
- this.o = o;
- this.s = s;
- }
- public void run() {
- System.out.println("tried");
- try {
- ObjectOutputStream outStream = new ObjectOutputStream(s.getOutputStream());
- outStream.writeObject(o);
- outStream.flush();
- outStream.reset();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * Starts a thread to write an object to every client.
- * @param Object o
- */
- public void send(Object o) {
- Runnable sendMany = new SendMany(o);
- sendAll = new Thread(sendMany);
- sendAll.start();
- }
- /**
- * A thread that calls send() for each client in the Set2DArray clients.
- * @author xPhilosx
- *
- */
- private class SendMany implements Runnable {
- private Object o;
- public SendMany(Object o) {
- this.o = o;
- }
- /**
- * Loops through all the clients and will call send() (spawning a new thread) to
- * write an object across the network to each client.
- */
- public void run() {
- System.out.println("total to send: " + clients.size());
- for (int i = 0; i < clients.size(); i++) {
- System.out.println("check");
- Socket s = (Socket) clients.get(i);
- send(s, o);
- }
- }
- }
- /**
- * Starts a thread to connect and listen to a server.
- * @param String IP
- * @param int port
- */
- public void connect(String IP, int port) {
- //Kills the current connection if one is alive.
- if (connect != null && connect.isAlive())
- close();
- //Starts the thread.
- Runnable connectTo = new ConnectTo(IP, port);
- connect = new Thread(connectTo, "self");
- connect.start();
- }
- /**
- * A thread that connects to a server specified by IP and port. Sends initial handshake,
- * and creates an infinite loop that will listen for traffic and respond accordingly.
- * @author xPhilosx
- *
- */
- private class ConnectTo implements Runnable {
- private String IP;
- private int port;
- public ConnectTo(String IP, int port) {
- this.IP = IP;
- this.port = port;
- }
- public void run() {
- try {
- socket = new Socket(IP, port);
- while (alive) {
- //Sets up the input stream
- System.out.println("waiting, faithfully");
- ObjectInputStream inStream = new ObjectInputStream(socket.getInputStream());
- Object readStream = inStream.readObject();
- //Decides how to process the received object.
- if (readStream instanceof String)
- System.out.println(readStream);
- }
- } catch (UnknownHostException e) {
- } catch (IOException e) {
- } catch (ClassNotFoundException e) {
- //e.printStackTrace();
- }
- }
- }
- /**
- * Closes out all the threads and closes all open sockets. This will kill all the clients.
- * @return
- * @throws IOException
- */
- public void close() {
- alive = false;
- //Shuts down each open socket and then closes the corresponding thread.
- try {
- //Closes the client socket on the *client side*
- if (socket != null && socket.isConnected()) {
- socket.close();
- connect = null;
- }
- //Loops through all the client sockets on the *server side* and shuts them down.
- for (int i = 0; i < clients.size(); i++) {
- Socket temp = (Socket) clients.get(i);
- if (temp.isConnected())
- temp.close();
- }
- //Closes the server socket and exits the server daemon thread.
- if (serverSocket != null && serverSocket.isClosed()) {
- serverSocket.close();
- server = null;
- }
- } catch (IOException e) {
- }
- }
- /**
- * Returns the client list
- * @return
- */
- public Set2DArray getClients() {
- return clients;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement