import java.io.*; import java.net.*; public class FlipServer{ static final int size = 6; // how many keys wide and high static final int port = 8199; // agreed upon w/ NetInterface, unassigned private MulticastOutputStream out; // communicates to the clients private boolean pushedOddTimes[][]; // keeps track of history /** The addOut method is used to add another output stream that should * receive the pushes (row and column numbers); this is used when * a new client connects. Buttons that were pushed earlier are * also sent to the new stream, provided they were pushed an odd number * of times. */ public void addOut(OutputStream newOut){ try{ for(int row = 0; row < size; row++){ for(int col = 0; col < size; col++){ if(pushedOddTimes[row][col]){ newOut.write(row); newOut.write(col); } } } } catch(Exception e){ System.err.println(e); } out.add(newOut); } /** The removeOut method is used to remove one of the output streams * to which pushes (row and column numbers) are being sent; this is * used when the thread tending a particular client connection notices * that the client has closed the connection */ public void removeOut(OutputStream oldOut){ out.remove(oldOut); } /** The push method is used to record and transmit a push; it is used * by a client connection thread that has received a row and column */ public void push(int row, int col){ pushedOddTimes[row][col] = !pushedOddTimes[row][col]; try{ out.write(row); out.write(col); } catch(Exception e){ System.err.println(e); } } public static void main(String[] args){ FlipServer server = new FlipServer(); try{ ServerSocket ss = new ServerSocket(port); while(true){ Socket s = ss.accept(); OutputStream newOut = s.getOutputStream(); server.addOut(newOut); new ClientConnectionThread(server, s, newOut); } } catch(Exception e){ System.err.println(e); System.exit(1); } } private FlipServer(){ pushedOddTimes = new boolean[size][size]; out = new MulticastOutputStream(); } } class ClientConnectionThread extends Thread{ private FlipServer server; private Socket sock; private OutputStream out; private InputStream in; ClientConnectionThread(FlipServer srvr, Socket s, OutputStream o) throws IOException { server = srvr; sock = s; out = o; in = s.getInputStream(); start(); // start thread listening for incoming pushes } public void run(){ try{ while(true){ int row = in.read(); int col = in.read(); if(col == -1){ // end of data indication break; // so break out of loop (to the removeOut) } server.push(row, col); } server.removeOut(out); // the client died, so don't send it any more } catch(Exception e){ System.err.println(e); } finally{ try{ sock.close(); } catch(Exception e){ System.err.println(e); } } } }