import java.io.*; import java.net.*; public class NetFlip extends Flip { private NetInterface ni; public static void main(String args[]){ if(args.length != 1){ System.err.println("Usage: java NetFlip serverhost"); } else { new NetFlip(args[0]); } } public NetFlip(String server){ super(); setTitle("NetFlip"); ni = new NetInterface(server, this); } public void pushButton(int row, int col){ // This overrides the pushButton method from the Flip class // and arranges that when the user pushes a button, the push // is sent over the network to the server, and hence all clients. ni.sendPush(row, col); } public void pushLocalButton(int row, int col){ // This is used when the server tells us about a pushing of // a button, to just do the response (flipping) on this one client. // This is the same as what happens in normal non-Net Flip when // the user pushes a button, so we just use the Flip class's method. super.pushButton(row, col); } } class NetInterface extends Thread { static final int port = 8199; // agreed upon with FlipServer, unassigned NetFlip nFlip; Socket sock; InputStream in; OutputStream out; public NetInterface(String server, NetFlip nf){ nFlip = nf; try{ sock = new Socket(server, port); in = sock.getInputStream(); out = sock.getOutputStream(); start(); // start thread listening for pushes from the server } catch(Exception e){ System.err.println(e); System.err.println("Trouble connecting to server; running standalone."); } } public void run(){ // runs in the thread listening to the server try{ while(true){ int row = in.read(); int col = in.read(); if(col == -1){ // end of data indication break; // break out of loop to closeDown } nFlip.pushLocalButton(row, col); } closeDown(); // this means the server died -- shut down connection } catch(Exception e){ System.err.println(e); System.exit(1); } } public void sendPush(int row, int col){ if(out == null){ // no server connection nFlip.pushLocalButton(row, col); // so locally fake the round-trip } else { try{ out.write(row); out.write(col); } catch(Exception e){ System.err.println(e); System.exit(1); } } } private void closeDown() throws IOException { out.close(); in.close(); sock.close(); System.err.println("Server shut down; reverting to standalone operation."); out = null; // so we know to do the pushing locally } }