Presentation is loading. Please wait.

Presentation is loading. Please wait.

Networking.

Similar presentations


Presentation on theme: "Networking."— Presentation transcript:

1 Networking

2 Introduction In this chapter Socket-based communications
View networking like file I/O Stream sockets When connection in place, data flows in continuous streams TCP protocol Preferred

3 Establishing a Simple Server (Using Stream Sockets)
Creating a Java server Create ServerSocket object ServerSocket s = new ServerSocket( port, queueLength ); Register port number and set max number of waiting clients Binds server to port, waits for clients Server listens indefinitely (blocks) for clients Socket connection = s.accept() Connections managed by Socket objects Returns Socket when connection established

4 Establishing a Simple Client (Using Stream Sockets)
Creating a Java server Get I/O objects for communication OutputStream - sends info to client InputStream - gets info from client Server's input stream is client's output stream, and vice versa Use Socket object to get references to streams connection.getInputStream() connection.getOutputStream() Methods write and read Send individual bytes

5 Establishing a Simple Client (Using Stream Sockets)
Creating a Java server Chaining stream types (sending objects and data, not bytes) ObjectInputStream input = new ObjectInputStream( connection.getInputStream() ) Processing phase Server/client communicate using InputStream and OutputStream Termination Transmission complete Method close (of Socket) connection.close() Networking appears as sequential file I/O Sockets simplify networking

6 Establishing a Simple Client (Using Stream Sockets)
Creating a Java client Create Socket to connect to server Socket connection = new Socket( serverAddress, port ) If successful, returns Socket Else throws subclass of IOException Get stream objects connection.getInputStream() connection.getOutputStream() Use chaining if transmitting objects and data, not pure bytes ObjectInputStream, ObjectOutputStream

7 Establishing a Simple Client (Using Stream Sockets)
Creating a Java client Processing phase Communicate using stream objects Termination Transmission complete connection.close() (close Socket) Client must determine when server done read returns -1 when eof found ObjectInputStream generates EOFException

8 Client/Server Interaction with Stream Socket Connections
Upcoming program Simple client/server chat application Use stream sockets Client connects, transmit String objects do-while loop to get input Event handler calls sendData method to send output When either sends TERMINATE, connection terminates Server waits for next client GUI:

9 Client/Server Interaction with Stream Socket Connections
Once connection (Socket) established getInetAddress() - returns InetAddress object getHostName() - returns client's host name Create ObjectOutputStream flush() Sends stream header to client Required by client's ObjectInputStream connection.getInetAddress().getHostName() ); output = new ObjectOutputStream( connection.getOutputStream() ); output.flush();

10 Client/Server Interaction with Stream Socket Connections
Send/receive data Method sendData called by event handler Buffer flushed after every transmission Sets cursor position to end of text Allows JTextArea to scroll with text Server processes single connection at a time More likely to have separate threads for each connection private void sendData( String s ) { output.writeObject( "SERVER>>> " + s ); output.flush(); display.append( "\nSERVER>>>" + s ); display.setCaretPosition( display.getText().length() );

11 1. Constructor 1.1 GUI components
1 // Fig. 21.3: Server.java 2 // Set up a Server that will receive a connection 3 // from a client, send a string to the client, 4 // and close the connection. 5 import java.io.*; 6 import java.net.*; 7 import java.awt.*; 8 import java.awt.event.*; 9 import javax.swing.*; 10 11 public class Server extends JFrame { 12 private JTextField enter; 13 private JTextArea display; 14 ObjectOutputStream output; 15 ObjectInputStream input; 16 17 public Server() 18 { super( "Server" ); 20 Container c = getContentPane(); 22 enter = new JTextField(); enter.setEnabled( false ); 1. Constructor 1.1 GUI components

12 1.2 Event handler 1.3 GUI 2. Method runServer 2.1 ServerSocket
34 display = new JTextArea(); c.add( new JScrollPane( display ), BorderLayout.CENTER ); 38 setSize( 300, 150 ); show(); 41 } 42 43 public void runServer() 44 { ServerSocket server; Socket connection; int counter = 1; 48 try { // Step 1: Create a ServerSocket. server = new ServerSocket( 5000, 100 ); 52 enter.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { sendData( e.getActionCommand() ); } } ); c.add( enter, BorderLayout.NORTH ); 1.2 Event handler 1.3 GUI 2. Method runServer 2.1 ServerSocket The event handlers calls method sendData, using text in JTextField as argument. Register port 5000, server will allow 100 clients to wait in queue.

13 2.2 accept 2.3 getHostName 2.4 Get streams 2.5 writeObject 2.6 Loop
while ( true ) { Infinite loop to wait for connections from clients. // Step 2: Wait for a connection. display.setText( "Waiting for connection\n" ); 2.2 accept 2.3 getHostName 2.4 Get streams 2.5 writeObject 2.6 Loop connection = server.accept(); 57 Wait for connection (server.accept() waits indefinitely). display.append( "Connection " + counter + " received from: " + connection.getInetAddress().getHostName() ); 61 Display host location. // Step 3: Get input and output streams. output = new ObjectOutputStream( connection.getOutputStream() ); output.flush(); Set up I/O streams, flush buffer (sends stream data). Send confirmation message. input = new ObjectInputStream( connection.getInputStream() ); display.append( "\nGot I/O streams\n" ); 69 // Step 4: Process connection. String message = "SERVER>>> Connection successful"; output.writeObject( message ); output.flush(); Loop to get input. Set cursor to end of text. enter.setEnabled( true ); 76 do { try { message = (String) input.readObject(); display.append( "\n" + message ); display.setCaretPosition( display.getText().length() ); }

14 2.6 Loop 2.7 close 3. Method sendData 3.1 writeObject 3.2 flush
catch ( ClassNotFoundException cnfex ) { display.append( "\nUnknown object type received" ); } } while ( !message.equals( "CLIENT>>> TERMINATE" ) ); 89 // Step 5: Close connection. display.append( "\nUser terminated connection" ); enter.setEnabled( false ); output.close(); input.close(); connection.close(); 96 counter; } } Loop until TERMINATE string sent. 2.6 Loop 2.7 close 3. Method sendData 3.1 writeObject 3.2 flush Close connection and I/O streams. catch ( EOFException eof ) { System.out.println( "Client terminated connection" ); } catch ( IOException io ) { Send String object to client. Flush buffer to ensure it is sent, and update server's display. io.printStackTrace(); } } 107 private void sendData( String s ) { try { output.writeObject( "SERVER>>> " + s ); output.flush(); display.append( "\nSERVER>>>" + s ); }

15 4. main 115 catch ( IOException cnfex ) { 116 display.append(
133 app.runServer(); } 136 } catch ( IOException cnfex ) { display.append( "\nError writing object" ); } } 120 public static void main( String args[] ) { Server app = new Server(); 124 app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); 4. main

16 Client/Server Interaction with Stream Socket Connections
Similar to server Creates same GUI Loops to wait for input Sends output through event handler and sendData

17 Client/Server Interaction with Stream Socket Connections
Create Socket with two arguments Internet address of server and port number static method getByName (Class InetAddress) Returns InetAddress object Takes String Could have taken "localhost" or called static method getLocalHost Create I/O objects as before Output of server is input of client client = new Socket( InetAddress.getByName( " " ), 5000 );

18 1. Constructor 1.1 GUI 1 // Fig. 21.4: Client.java
2 // Set up a Client that will read information sent 3 // from a Server and display the information. 4 import java.io.*; 5 import java.net.*; 6 import java.awt.*; 7 import java.awt.event.*; 8 import javax.swing.*; 9 10 public class Client extends JFrame { 11 private JTextField enter; 12 private JTextArea display; 13 ObjectOutputStream output; 14 ObjectInputStream input; 15 String message = ""; 16 17 public Client() 18 { super( "Client" ); 20 Container c = getContentPane(); 22 enter = new JTextField(); enter.setEnabled( false ); 1. Constructor 1.1 GUI

19 1.2 Event handler 1.3 GUI 2. Method runClient 2.1 Socket
enter.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { sendData( e.getActionCommand() ); } } ); c.add( enter, BorderLayout.NORTH ); 1.2 Event handler 1.3 GUI 2. Method runClient 2.1 Socket Client gets text from JTextField and calls sendData. 34 display = new JTextArea(); c.add( new JScrollPane( display ), BorderLayout.CENTER ); 38 setSize( 300, 150 ); show(); 41 } Create Socket to server, make connection. 42 43 public void runClient() 44 { Socket client; 46 try { // Step 1: Create a Socket to make connection. display.setText( "Attempting connection\n" ); client = new Socket( InetAddress.getByName( " " ), 5000 ); 52 53 54 55

20 67 // Step 3: Process connection.
enter.setEnabled( true ); 69 do { try { message = (String) input.readObject(); display.append( "\n" + message ); display.setCaretPosition( display.getText().length() ); } catch ( ClassNotFoundException cnfex ) { display.append( "\nUnknown object type received" ); } } while ( !message.equals( "SERVER>>> TERMINATE" ) ); 82 display.append( "Connected to: " + client.getInetAddress().getHostName() ); 58 // Step 2: Get the input and output streams. output = new ObjectOutputStream( client.getOutputStream() ); output.flush(); input = new ObjectInputStream( client.getInputStream() ); display.append( "\nGot I/O streams\n" ); 66 2.2 I/O streams 2.3 flush 2.4 Loop Code similar to server. Create I/O objects, flush buffer, loop to wait for and process input.

21 2.5 close 3. Method sendData 83 // Step 4: Close connection.
message = s; output.writeObject( "CLIENT>>> " + s ); output.flush(); display.append( "\nCLIENT>>>" + s ); } catch ( IOException cnfex ) { display.append( "\nError writing object" ); } } 110 // Step 4: Close connection. display.append( "Closing connection.\n" ); input.close(); output.close(); client.close(); } catch ( EOFException eof ) { System.out.println( "Server terminated connection" ); } catch ( IOException e ) { e.printStackTrace(); } 95 } 96 97 private void sendData( String s ) 98 { try { 2.5 close 3. Method sendData

22 4. main Program Output 111 public static void main( String args[] )
{ Client app = new Client(); 114 app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); 123 app.runClient(); } 126 } 127 4. main Program Output

23 Program Output

24 Connectionless Client/Server Interaction with Datagrams
Connection-oriented interaction Like phone call Have connection to other end Connection maintained for duration of call, even if not talking Connectionless interaction Like sending postal mail Use datagrams, packets of data If large packet, break into smaller pieces Send separately May arrive out of order or not arrive at all Duplicates may arrive

25 Connectionless Client/Server Interaction with Datagrams
DatagramSocket( port ) Binds server to port DatagramPacket( byteArray, byteArray.length ) Create DatagramPacket to store received packet byteArray stores data Method receive( packetToStore ) Blocks until packet arrives, stores in packetToStore socket = new DatagramSocket( 5000 ); byte data[] = new byte[ 100 ]; receivePacket = new DatagramPacket( data, data.length ); socket.receive( receivePacket );

26 Connectionless Client/Server Interaction with Datagrams
getAddress - returns InetAddress getPort, getLength - return integers getData - returns byte array Used in String constructor to create string display.append( "\nPacket received:" + "\nFrom host: " + receivePacket.getAddress() + "\nHost port: " + receivePacket.getPort() + "\nLength: " + receivePacket.getLength() + "\nContaining:\n\t" + new String( receivePacket.getData(), 0, receivePacket.getLength() ) );

27 Connectionless Client/Server Interaction with Datagrams
Echo packet back to client DatagramPacket( byteArray, length, InetAddress, port ) Method send( packetToSend ) sendPacket = new DatagramPacket( receivePacket.getData(), receivePacket.getLength(), receivePacket.getPort() ); socket.send( sendPacket ); receivePacket.getAddress(),

28 1. Declarations 1.1 DatagramSocket
1 // Fig. 21.5: Server.java 2 // Set up a Server that will receive packets from a 3 // client and send packets to a client. 1. Declarations 1.1 DatagramSocket 4 import java.io.*; 5 import java.net.*; 6 import java.awt.*; 7 import java.awt.event.*; 8 import javax.swing.*; 9 10 public class Server extends JFrame { 11 private JTextArea display; 12 13 private DatagramPacket sendPacket, receivePacket; 14 private DatagramSocket socket; 15 16 public Server() 17 { super( "Server" ); 19 display = new JTextArea(); getContentPane().add( new JScrollPane( display), BorderLayout.CENTER ); setSize( 400, 300 ); Create new DatagramSocket, binds server to port. show(); 25 try { socket = new DatagramSocket( 5000 ); }

29 Loop to wait for packets. 2. Method waitForPackets
catch( SocketException se ) { se.printStackTrace(); System.exit( 1 ); } 33 } Loop to wait for packets. 2. Method waitForPackets 2.1 receivePacket 2.2 receive 2.3 Process packet 2.4 Echo packet 34 35 public void waitForPackets() 36 { Create new DatagramPacket to receive info. while ( true ) { try { // set up packet byte data[] = new byte[ 100 ]; receivePacket = new DatagramPacket( data, data.length ); 43 // wait for packet socket.receive( receivePacket ); Gather and display packet data. Convert byte array to a String. 46 // process packet display.append( "\nPacket received:" + "\nFrom host: " + receivePacket.getAddress() + "\nHost port: " + receivePacket.getPort() + "\nLength: " + receivePacket.getLength() + "\nContaining:\n\t" + new String( receivePacket.getData(), 0, receivePacket.getLength() ) ); 55 Create packet back to client. // echo information from packet back to client display.append( "\n\nEcho data to client..."); sendPacket = new DatagramPacket( receivePacket.getData(),

30 Send packet back to client.
receivePacket.getLength(), receivePacket.getAddress(), receivePacket.getPort() ); 2.5 send 3. main socket.send( sendPacket ); Send packet back to client. display.append( "Packet sent\n" ); display.setCaretPosition( display.getText().length() ); } catch( IOException io ) { display.append( io.toString() + "\n" ); io.printStackTrace(); } } 73 } 74 75 public static void main( String args[] ) 76 { Server app = new Server(); 78 app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); 87 app.waitForPackets(); 89 } 90 }

31 Program Output

32 Connectionless Client/Server Interaction with Datagrams
Similar to server Has JTextField Sends packets with event handler for JTextField Convert String to byteArray String.getBytes() Have loop to receive echoed packets from server Constructor needs no arguments Uses next available port Server gets client's port number as part of DatagramPacket socket = new DatagramSocket();

33 1. Constructor 1.1 GUI 1.2 Register event handler
1 // Fig. 21.6: Client.java 2 // Set up a Client that will send packets to a 3 // server and receive packets from a server. 4 import java.io.*; 5 import java.net.*; 6 import java.awt.*; 7 import java.awt.event.*; 8 import javax.swing.*; 9 10 public class Client extends JFrame implements ActionListener { 11 private JTextField enter; 12 private JTextArea display; 13 14 private DatagramPacket sendPacket, receivePacket; 15 private DatagramSocket socket; 16 17 public Client() 18 { super( "Client" ); 20 enter = new JTextField( "Type message here" ); enter.addActionListener( this ); getContentPane().add( enter, BorderLayout.NORTH ); display = new JTextArea(); getContentPane().add( new JScrollPane( display ), BorderLayout.CENTER ); setSize( 400, 300 ); show(); 29 1. Constructor 1.1 GUI 1.2 Register event handler

34 No argument constructor.
try { No argument constructor. socket = new DatagramSocket(); } 1.3 DatagramSocket 2. waitForPackets 2.1 DatagramPacket 2.2 receive 2.3 Process packet catch( SocketException se ) { se.printStackTrace(); System.exit( 1 ); } 37 } 38 39 public void waitForPackets() 40 { while ( true ) { try { // set up packet byte data[] = new byte[ 100 ]; receivePacket = new DatagramPacket( data, data.length ); 47 // wait for packet socket.receive( receivePacket ); 50 // process packet display.append( "\nPacket received:" + "\nFrom host: " + receivePacket.getAddress() + "\nHost port: " + receivePacket.getPort() + "\nLength: " + receivePacket.getLength() + "\nContaining:\n\t" + new String( receivePacket.getData(), 0, receivePacket.getLength() ) ); Similar to server, loop to receive echoed packets.

35 3. actionPerformed 3.1 Create packet 3.2 send
67 } 68 69 public void actionPerformed( ActionEvent e ) 70 { try { display.append( "\nSending packet containing: " + e.getActionCommand() + "\n" ); 74 String s = e.getActionCommand(); byte data[] = s.getBytes(); 77 sendPacket = new DatagramPacket( data, data.length, InetAddress.getLocalHost(), 5000 ); socket.send( sendPacket ); display.append( "Packet sent\n" ); display.setCaretPosition( display.getText().length() ); 84 } catch ( IOException exception ) { display.append( exception.toString() + "\n" ); exception.printStackTrace(); } 90 } display.setCaretPosition( display.getText().length() ); } catch( IOException exception ) { display.append( exception.toString() + "\n" ); exception.printStackTrace(); } } 3. actionPerformed 3.1 Create packet 3.2 send Convert String to a byte array, use to initialize DatagramPacket.

36 Program Output 91 92 public static void main( String args[] ) 93 {
System.exit( 0 ); } } ); 104 app.waitForPackets(); } 107 } 91 92 public static void main( String args[] ) 93 { Client app = new Client(); 95 app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { Program Output

37 Client/Server Tic-Tac-Toe Using a Multithreaded Server
Create application allowing two clients to connect to server When each client connects Player object created in separate thread Manages connection Server maintains board information Byte array represents board Determines if moves are valid Each client has own GUI Has board information

38 Client/Server Tic-Tac-Toe Using a Multithreaded Server
Server creates ServerSocket Waits for two connections, creates two Player objects Initialize Player objects Connection to respective client, reference to server, number for ( int i = 0; i < players.length; i++ ) { players[ i ] = new Player( server.accept(), this, i ); players[ i ].start(); server = new ServerSocket( 5000, 2 ); connection = s; 139class Player extends Thread { 148 public Player( Socket s, TicTacToeServer t, int num ) control = t; number = num;

39 Client/Server Tic-Tac-Toe Using a Multithreaded Server
Update server (display) and send client their mark (X or O) Suspend Player X Notify Player X after Player O connects Code comes after loop to initialize both Players control.display( "Player " + ( number == 0 ? 'X' : 'O' ) + " connected" ); output.writeChar( mark ); while ( threadSuspended ) wait(); public void run() if ( mark == 'X' ) { synchronized( this ) { synchronized ( players[ 0 ] ) { players[ 0 ].threadSuspended = false; players[ 0 ].notify();

40 Client/Server Tic-Tac-Toe Using a Multithreaded Server
Game begins playing run method executes while loop Read integer representing move from client Test if valid (control.validMove) If so, send message to server and client while ( !done ) { int location = input.readInt(); if ( control.validMove( location, number ) ) { control.display( "loc: " + location ); output.writeUTF( "Valid move." );

41 Client/Server Tic-Tac-Toe Using a Multithreaded Server
Method validMove synchronized - one move at a time If player not currentPlayer, put in wait state When other player moves, notify 79 public synchronized boolean validMove( int loc, int player ) while ( player != currentPlayer ) { wait();

42 Client/Server Tic-Tac-Toe Using a Multithreaded Server
notify(); // tell waiting player to continue return true; if ( !isOccupied( loc ) ) { board[ loc ] = (byte) ( currentPlayer == 0 ? 'X' : 'O' ); currentPlayer = ( currentPlayer + 1 ) % 2; players[ currentPlayer ].otherPlayerMoved( loc ); Checks if location occupied If not, updates byte array, currentPlayer otherPlayerMoved - informs other client of move Notify waiting client Return true (valid move)

43 1. Constructor 1.1 Initialization 1.2 ServerSocket
1 // Fig. 21.7: TicTacToeServer.java 2 // This class maintains a game of Tic-Tac-Toe for two 3 // client applets. 1. Constructor 1.1 Initialization 1.2 ServerSocket 4 import java.awt.*; 5 import java.awt.event.*; 6 import java.net.*; 7 import java.io.*; 8 import javax.swing.*; 9 10 public class TicTacToeServer extends JFrame { 11 private byte board[]; 12 private boolean xMove; Use nine element byte array to represent board. Create Player array. 13 private JTextArea output; 14 private Player players[]; 15 private ServerSocket server; 16 private int currentPlayer; 17 18 public TicTacToeServer() 19 { super( "Tic-Tac-Toe Server" ); Server creates ServerSocket to get connections. 21 board = new byte[ 9 ]; xMove = true; players = new Player[ 2 ]; currentPlayer = 0; 26 // set up ServerSocket try { server = new ServerSocket( 5000, 2 ); }

44 1.3 GUI 2. Method execute 2.1 Initialize players
31 32 33 1.3 GUI 2. Method execute 2.1 Initialize players catch( IOException e ) { e.printStackTrace(); System.exit( 1 ); } 38 output = new JTextArea(); getContentPane().add( output, BorderLayout.CENTER ); output.setText( "Server awaiting connections\n" ); 42 setSize( 300, 300 ); show(); 45 } 46 47 // wait for two connections so game can be played Initialize Player objects with client connection. Player X begins in wait state. 48 public void execute() 49 { for ( int i = 0; i < players.length; i++ ) { try { players[ i ] = new Player( server.accept(), this, i ); players[ i ].start(); } catch( IOException e ) { e.printStackTrace(); System.exit( 1 ); } }

45 4. Method validMove (synchronized)
61 // Player X is suspended until Player O connects. // Resume player X now. 2.2 notify player X 3. Method display 4. Method validMove (synchronized) synchronized ( players[ 0 ] ) { players[ 0 ].threadSuspended = false; players[ 0 ].notify(); Notify player X to resume execution. } 68 69 } 70 71 public void display( String s ) 72 { output.append( s + "\n" ); 74 } Allow only one move at a time. 75 76 // Determine if a move is valid. 77 // This method is synchronized because only one move can be 78 // made at a time. 79 public synchronized boolean validMove( int loc, int player ) 81 { boolean moveDone = false; 83 84 85 while ( player != currentPlayer ) { try { If player is not the current player, send to wait state. wait(); }

46 4.1 Update information 5. isOccupied 6. gameOver
catch( InterruptedException e ) { e.printStackTrace(); } If location unoccupied, update current player, inform other player of move, board, and notify waiting players. 4.1 Update information 5. isOccupied 6. gameOver } 94 if ( !isOccupied( loc ) ) { board[ loc ] = (byte) ( currentPlayer == 0 ? 'X' : 'O' ); currentPlayer = ( currentPlayer + 1 ) % 2; players[ currentPlayer ].otherPlayerMoved( loc ); notify(); // tell waiting player to continue return true; } else return false; } 106 public boolean isOccupied( int loc ) { if ( board[ loc ] == 'X' || board [ loc ] == 'O' ) return true; else return false; } 114 public boolean gameOver() { // Place code here to test for a winner of the game return false; }

47 120 public static void main( String args[] ) { TicTacToeServer game = new TicTacToeServer(); 124 game.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); 132 7. main 8. Class Player game.execute(); } 135 } 136 137 138 // Player class to manage each Player as a thread 139 class Player extends Thread { private Socket connection; private DataInputStream input; private DataOutputStream output; private TicTacToeServer control; private int number; private char mark; protected boolean threadSuspended = true; 147

48 8.1 Constructor 8.2 I/O streams 8.3 otherPlayerMoved
public Player( Socket s, TicTacToeServer t, int num ) { Initialize with client connection, reference to server object, and player number. mark = ( num == 0 ? 'X' : 'O' ); 8.1 Constructor 8.2 I/O streams 8.3 otherPlayerMoved 151 connection = s; 153 try { input = new DataInputStream( connection.getInputStream() ); output = new DataOutputStream( connection.getOutputStream() ); } catch( IOException e ) { e.printStackTrace(); System.exit( 1 ); } 164 control = t; number = num; } Inform Player of other's move. 168 public void otherPlayerMoved( int loc ) { try { output.writeUTF( "Opponent moved" ); output.writeInt( loc ); } catch ( IOException e ) { e.printStackTrace(); } } 177

49 8.4 run 8.4.1 Inform server 8.4.2 Send mark 8.4.3 Player X waits
public void run() Server displays connected client. Mark (X or O) sent to client. { boolean done = false; 8.4 run 8.4.1 Inform server 8.4.2 Send mark 8.4.3 Player X waits 181 try { control.display( "Player " + ( number == 0 ? 'X' : 'O' ) + " connected" ); output.writeChar( mark ); output.writeUTF( "Player " + ( number == 0 ? "X connected\n" : "O connected, please wait\n" ) ); 189 190 // wait for another player to arrive if ( mark == 'X' ) { output.writeUTF( "Waiting for another player" ); 194 try { Player X waits (so Player O can connect). Once Player O connects, X can move. synchronized( this ) { while ( threadSuspended ) wait(); } } catch ( InterruptedException e ) { e.printStackTrace(); } 204 output.writeUTF( "Other player connected. Your move." ); } 208

50 8.5 Loop for input 8.6 validMove
// Play game while ( !done ) { int location = input.readInt(); 8.5 Loop for input 8.6 validMove 212 if ( control.validMove( location, number ) ) { control.display( "loc: " + location ); Loop and get input. Check validity, and inform server and client. output.writeUTF( "Valid move." ); } else output.writeUTF( "Invalid move, try again" ); 219 if ( control.gameOver() ) done = true; } 223 connection.close(); } catch( IOException e ) { e.printStackTrace(); System.exit( 1 ); } } 231 }

51 Program Output

52 Client/Server Tic-Tac-Toe Using a Multithreaded Server
Creates GUI Uses nine Square objects (extend JPanel) start method Connects to server Gets I/O streams

53 Client/Server Tic-Tac-Toe Using a Multithreaded Server
Implements interface Runnable, so separate thread can execute read input Executes run method, which loops and reads input outputThread = new Thread( this ); outputThread.start(); 11public class TicTacToeClient extends JApplet implements Runnable {

54 Client/Server Tic-Tac-Toe Using a Multithreaded Server
Method run handles input Sets player's mark Loops, gets input, calls processMessage while ( true ) { String s = input.readUTF(); processMessage( s ); } 94 public void run() 95 { myMark = input.readChar();

55 Client/Server Tic-Tac-Toe Using a Multithreaded Server
Method processMessage Perform actions depending on String received Listen for MouseEvents If Square clicked, setCurrentSquare public void processMessage( String s ) if ( s.equals( "Valid move." ) ) { else if ( s.equals( "Invalid move, try again" ) ) { else if ( s.equals( "Opponent moved" ) ) { display.append( "Valid move, please wait.\n" ); currentSquare.setMark( myMark ); currentSquare.repaint(); }

56 1. implements Runnable 1.1 Declarations 1.2 GUI
1 // Fig. 21.8: TicTacToeClient.java 2 // Client for the TicTacToe program 3 import java.awt.*; 1. implements Runnable 1.1 Declarations 1.2 GUI 4 import java.awt.event.*; Allows applet to create a thread, used to get input. 5 import java.net.*; 6 import java.io.*; 7 import javax.swing.*; 8 9 // Client class to let a user play Tic-Tac-Toe with 10 // another user across a network. 11 public class TicTacToeClient extends JApplet implements Runnable { 13 private JTextField id; 14 private JTextArea display; 15 private JPanel boardPanel, panel2; 16 private Square board[][], currentSquare; 17 private Socket connection; 18 private DataInputStream input; 19 private DataOutputStream output; 20 private Thread outputThread; 21 private char myMark; 22 private boolean myTurn; 23 24 // Set up user-interface and board 25 public void init() 26 { display = new JTextArea( 4, 30 ); display.setEditable( false ); getContentPane().add( new JScrollPane( display ), BorderLayout.SOUTH );

57 Register event handlers for each Square.
boardPanel.setLayout( layout ); 35 36 board = new Square[ 3 ][ 3 ]; 38 // When creating a Square, the location argument to the // constructor is a value from 0 to 8 indicating the // position of the Square on the board. Values 0, 1, // and 2 are the first row, values 3, 4, and 5 are the // second row. Values 6, 7, and 8 are the third row. for ( int row = 0; row < board.length; row++ ) { for ( int col = 0; col < board[ row ].length; col++ ) { board[ row ][ col ] = new Square( ' ', row * 3 + col ); board[ row ][ col ].addMouseListener( new SquareListener( this, board[ row ][ col ] ) ); 53 boardPanel.add( board[ row ][ col ] ); } } 57 id = new JTextField(); id.setEditable( false ); 60 31 boardPanel = new JPanel(); GridLayout layout = new GridLayout( 3, 3, 0, 0 ); 1.3 GUI 1.4 Event handlers Register event handlers for each Square.

58 Get connection to server.
getContentPane().add( id, BorderLayout.NORTH ); 62 panel2 = new JPanel(); panel2.add( boardPanel, BorderLayout.CENTER ); getContentPane().add( panel2, BorderLayout.CENTER ); 66 } 2. start 2.1 Socket 2.2 Thread 67 68 // Make connection to server and get associated streams. 69 // Start separate thread to allow this applet to 70 // continually update its output in text area display. 71 public void start() Get connection to server. 72 { try { connection = new Socket( InetAddress.getByName( " " ), 5000 ); input = new DataInputStream( connection.getInputStream() ); output = new DataOutputStream( connection.getOutputStream() ); } catch ( IOException e ) { Create new thread, which executes method run. e.printStackTrace(); } 84 outputThread = new Thread( this ); outputThread.start(); 87 } 88 89 90 91

59 3. run 3.1 Get mark 3.2 Loop for input
myTurn = ( myMark == 'X' ? true : false ); } catch ( IOException e ) { e.printStackTrace(); } 105 // Receive messages sent to client while ( true ) { try { String s = input.readUTF(); processMessage( s ); } catch ( IOException e ) { e.printStackTrace(); } } } 117 92 // Control thread that allows continuous update of the 93 // text area display. 94 public void run() 95 { // First get player's mark (X or O) try { myMark = input.readChar(); id.setText( "You are player \"" + myMark + "\"" ); 3. run 3.1 Get mark 3.2 Loop for input Get player's mark (first data sent) then loop for more input.

60 4. processMessage 4.1 setMark
// Process messages sent to client public void processMessage( String s ) { 4. processMessage 4.1 setMark if ( s.equals( "Valid move." ) ) { display.append( "Valid move, please wait.\n" ); currentSquare.setMark( myMark ); currentSquare.repaint(); Process string. If valid move, update current square with mark. If opponent moved, update appropriate square (in board array). } else if ( s.equals( "Invalid move, try again" ) ) { display.append( s + "\n" ); myTurn = true; } else if ( s.equals( "Opponent moved" ) ) { try { int loc = input.readInt(); 133 board[ loc / 3 ][ loc % 3 ].setMark( ( myMark == 'X' ? 'O' : 'X' ) ); board[ loc / 3 ][ loc % 3 ].repaint(); 137 display.append( "Opponent moved. Your turn.\n" ); myTurn = true; } 142 catch ( IOException e ) { e.printStackTrace(); } }

61 5. sendClickedSquare 6. setCurrentSquare 7. Class Square
165 public void setCurrentSquare( Square s ) { currentSquare = s; } 170 } 171 172 // Maintains one square on the board 173 class Square extends JPanel { private char mark; private int location; 176 else display.append( s + "\n" ); 149 display.setCaretPosition( display.getText().length() ); } 153 public void sendClickedSquare( int loc ) { if ( myTurn ) try { output.writeInt( loc ); myTurn = false; } catch ( IOException ie ) { ie.printStackTrace(); } } 5. sendClickedSquare 6. setCurrentSquare 7. Class Square

62 7. Class Square 177 public Square( char m, int loc) 178 {
197 public void paintComponent( Graphics g ) { super.paintComponent( g ); g.drawRect( 0, 0, 29, 29 ); g.drawString( String.valueOf( mark ), 11, 20 ); } 204 } public Square( char m, int loc) { mark = m; location = loc; setSize ( 30, 30 ); 182 setVisible(true); } 185 public Dimension getPreferredSize() { return ( new Dimension( 30, 30 ) ); } 189 public Dimension getMinimumSize() { return ( getPreferredSize() ); } 193 public void setMark( char c ) { mark = c; } 195 public int getSquareLocation() { return location; } 7. Class Square

63 8. Event handler 205 206 class SquareListener extends MouseAdapter {
private TicTacToeClient applet; private Square square; 209 public SquareListener( TicTacToeClient t, Square s ) { applet = t; square = s; } 215 public void mouseReleased( MouseEvent e ) { applet.setCurrentSquare( square ); applet.sendClickedSquare( square.getSquareLocation() ); } 221 } 8. Event handler

64 Program Output

65 Program Output

66 Security and the Network
Many Web browsers prevent file processing by applets (by default) Malicious applets could be a security risk Applets can usually only talk with the machine that downloaded it Trusted source Browsers can determine if applet came from trusted source If so, can be given more access


Download ppt "Networking."

Similar presentations


Ads by Google