Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Capítulo 33 - Redes - Liang-Java-Comp11e, Resumos de Informática

Redes, Networking

Tipologia: Resumos

2018

Compartilhado em 21/07/2018

dddmmm80-5
dddmmm80-5 🇧🇷

4.8

(4)

13 documentos

1 / 33

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
Objectives
To explain the terms: TCP, IP, domain name, domain name server,
stream-based communications, and packet-based communications
(§33.2).
To create servers using server sockets (§33.2.1) and clients using client
sockets (§33.2.2).
To implement Java networking programs using stream sockets
(§33.2.3).
To develop an example of a client/server application (§33.2.4).
To obtain Internet addresses using the InetAddress class (§33.3).
To develop servers for multiple clients (§33.4).
To send and receive objects on a network (§33.5).
To develop an interactive tic-tac-toe game played on the Internet
(§33.6).
Networking
CHAPTER
33
M33_LIAN0182_11_SE_C33.indd 1 5/29/17 7:41 AM
© 2018 Pearson Education, Inc., Hoboken, NJ. All rights reserved.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21

Pré-visualização parcial do texto

Baixe Capítulo 33 - Redes - Liang-Java-Comp11e e outras Resumos em PDF para Informática, somente na Docsity!

Objectives

■ ■ To explain the terms: TCP, IP, domain name, domain name server,

stream-based communications, and packet-based communications

■ ■ To create servers using server sockets (§33.2.1) and clients using client

sockets (§33.2.2).

■ ■ To implement Java networking programs using stream sockets

■ ■ To develop an example of a client/server application (§33.2.4).

■ ■ To obtain Internet addresses using the InetAddress class (§33.3).

■ ■ To develop servers for multiple clients (§33.4).

■ ■ To send and receive objects on a network (§33.5).

■ ■ To develop an interactive tic-tac-toe game played on the Internet

Networking

CHAPTER

33-2 Chapter 33 Networking

33.1 Introduction

Computer networking is used to send and receive messages among computers on the Internet.

To browse the Web or send an email, your computer must be connected to the Internet. The

Internet is the global network of millions of computers. Your computer can connect to the

Internet through an Internet Service Provider (ISP) using a dialup, DSL, or cable modem, or

through a local area network (LAN).

When a computer needs to communicate with another computer, it needs to know the other

computer’s address. An Internet Protocol (IP) address uniquely identifies the computer on the

Internet. An IP address consists of four dotted decimal numbers between 0 and 255 , such as

130.254.204.33. Since it is not easy to remember so many numbers, they are often mapped

to meaningful names called domain names , such as liang.armstrong.edu. Special servers called

Domain Name Servers (DNS) on the Internet translate host names into IP addresses. When a

computer contacts liang.armstrong.edu, it first asks the DNS to translate this domain name into

a numeric IP address then sends the request using the IP address.

The Internet Protocol is a low-level protocol for delivering data from one computer to

another across the Internet in packets. Two higher-level protocols used in conjunction with the

IP are the Transmission Control Protocol (TCP) and the User Datagram Protocol (UDP). TCP

enables two hosts to establish a connection and exchange streams of data. TCP guarantees

delivery of data and also guarantees that packets will be delivered in the same order in which

they were sent. UDP is a standard, low-overhead, connectionless, host-to-host protocol that is

used over the IP. UDP allows an application program on one computer to send a datagram to

an application program on another computer.

Java supports both stream-based and packet-based communications. Stream-based

communications use TCP for data transmission, whereas packet-based communications use UDP.

Since TCP can detect lost transmissions and resubmit them, transmissions are lossless and reli-

able. UDP, in contrast, cannot guarantee lossless transmission. Stream-based communications

are used in most areas of Java programming and are the focus of this chapter. Packet-based com-

munications are introduced in Supplement III.P, Networking Using Datagram Protocol.

33.2 Client/Server Computing

Java provides the ServerSocket class for creating a server socket, and the Socket

class for creating a client socket. Two programs on the Internet communicate through

a server socket and a client socket using I/O streams.

Networking is tightly integrated in Java. The Java API provides the classes for creating sockets

to facilitate program communications over the Internet. Sockets are the endpoints of logical

connections between two hosts and can be used to send and receive data. Java treats socket

communications much as it treats I/O operations; thus, programs can read from or write to

sockets as easily as they can read from or write to files.

Network programming usually involves a server and one or more clients. The client sends

requests to the server, and the server responds. The client begins by attempting to establish a

connection to the server. The server can accept or deny the connection. Once a connection is

established, the client and the server communicate through sockets.

The server must be running when a client attempts to connect to the server. The server waits

for a connection request from the client. The statements needed to create sockets on a server

and on a client are shown in Figure 33.1.

33.2.1 Server Sockets

To establish a server, you need to create a server socket and attach it to a port , which is where

the server listens for connections. The port identifies the TCP service on the socket. Port num-

bers range from 0 to 65536, but port numbers 0 to 1024 are reserved for privileged services.

Point

Key

IP address

domain name domain name server

TCP

UDP

stream-based communication packet-based communication

Point

Key

socket

server socket port

33-4 Chapter 33 Networking

Note The Socket constructor throws a java.net.UnknownHostException if the host cannot be found.

33.2.3 Data Transmission through Sockets

After the server accepts the connection, the communication between the server and the client

is conducted in the same way as for I/O streams. The statements needed to create the streams

and to exchange data between them are shown in Figure 33.2.

UnknownHostException

Figure 33.2 The server and client exchange data through I/O streams on top of the socket.

int port = 8000; int port = 8000;

Connection Request

I/O Streams

Server Client

DataInputStream in; DataOutputStream out; ServerSocket server; Socket socket;

server = new ServerSocket(port); socket = server.accept(); in = new DataInputStream (socket.getInputStream()); out = new DataOutputStream (socket.getOutputStream()); System.out.println(in.readDouble()); out.writeDouble(aNumber);

String host = "localhost" DataInputStream in; DataOutputStream out; Socket socket;

socket = new Socket(host, port); in = new DataInputStream (socket.getInputStream()); out = new DataOutputStream (socket.getOutputStream());

System.out.println(in.readDouble());

out.writeDouble(aNumber);

To get an input stream and an output stream, use the getInputStream() and

getOutputStream() methods on a socket object. For example, the following statements

create an InputStream stream called input and an OutputStream stream called output

from a socket:

InputStream input = socket.getInputStream(); OutputStream output = socket.getOutputStream();

The InputStream and OutputStream streams are used to read or write bytes. You can use

DataInputStream , DataOutputStream , BufferedReader , and PrintWriter to wrap on

the InputStream and OutputStream to read or write data, such as int , double , or String.

The following statements, for instance, create the DataInputStream stream input and the

DataOutputstream output to read and write primitive data values:

DataInputStream input = new DataInputStream (socket.getInputStream()); DataOutputStream output = new DataOutputStream (socket.getOutputStream());

The server can use input.readDouble() to receive a double value from the client, and

output.writeDouble(d) to send the double value d to the client.

Tip Recall that binary I/O is more efficient than text I/O because text I/O requires encoding and decoding. Therefore, it is better to use binary I/O for transmitting data between a server and a client to improve performance.

33.2 Client/Server Computing 33-

The client sends the radius through a DataOutputStream on the output stream socket, and the

server receives the radius through the DataInputStream on the input stream socket, as shown

in Figure 33.4a. The server computes the area and sends it to the client through a DataOutput-

Stream on the output stream socket, and the client receives the area through a DataInputStream

on the input stream socket, as shown in Figure 33.4b. The server and client programs are given in

Listings 33.1 and 33.2. Figure 33.5 contains a sample run of the server and the client.

Figure 33.3 The client sends the radius to the server; the server computes the area and

sends it to the client.

compute area Server Client

radius

area

33.2.4 A Client/Server Example

This example presents a client program and a server program. The client sends data to a server.

The server receives the data, uses it to produce a result, and then sends the result back to the

client. The client displays the result on the console. In this example, the data sent from the client

comprise the radius of a circle, and the result produced by the server is the area of the circle

(see Figure 33.3).

Figure 33.4 (a) The client sends the radius to the server. (b) The server sends the area to the client.

Server radius

DataInputStream

socket.getInputStream

socket

Network

radius

DataOutputStream

socket.getOutputStream

socket

Client

(a)

Server area

DataOutputStream

socket.getOutputStream

socket

Network

area

DataInputStream

socket.getInputStream

socket

Client

(b)

Figure 33.5 The client sends the radius to the server. The server receives it, computes the

area, and sends the area to the client.

Listing 33.1 Server.java

1 import java.io.; 2 import java.net.; 3 import java.util.Date;

33.2 Client/Server Computing 33-

Listing 33.2 Client.java

1 import java.io.; 2 import java.net.; 3 import javafx.application.Application; 4 import javafx.geometry.Insets; 5 import javafx.geometry.Pos; 6 import javafx.scene.Scene; 7 import javafx.scene.control.Label; 8 import javafx.scene.control.ScrollPane; 9 import javafx.scene.control.TextArea; 10 import javafx.scene.control.TextField; 11 import javafx.scene.layout.BorderPane; 12 import javafx.stage.Stage; 13 14 public class Client extends Application { 15 // IO streams 16 DataOutputStream toServer = null ; 17 DataInputStream fromServer = null ; 18 19 @Override // Override the start method in the Application class 20 public void start(Stage primaryStage) { 21 // Panel p to hold the label and text field 22 BorderPane paneForTextField = new BorderPane(); 23 paneForTextField.setPadding( new Insets( 5 , 5 , 5 , 5 )); 24 paneForTextField.setStyle( "-fx-border-color: green" ); 25 paneForTextField.setLeft( new Label( "Enter a radius: " )); 26 27 TextField tf = new TextField(); 28 tf.setAlignment(Pos.BOTTOM_RIGHT); 29 paneForTextField.setCenter(tf); 30 31 BorderPane mainPane = new BorderPane(); 32 // Text area to display contents 33 TextArea ta = new TextArea(); 34 mainPane.setCenter( new ScrollPane(ta)); 35 mainPane.setTop(paneForTextField); 36 37 // Create a scene and place it in the stage 38 Scene scene = new Scene(mainPane, 450 , 200 ); 39 primaryStage.setTitle( "Client" ); // Set the stage title 40 primaryStage.setScene(scene); // Place the scene in the stage 41 primaryStage.show(); // Display the stage 42 43 tf.setOnAction(e -> { 44 try { 45 // Get the radius from the text field 46 double radius = Double.parseDouble(tf.getText().trim()); 47 48 // Send the radius to the server 49 toServer.writeDouble(radius); 50 toServer.flush(); 51 52 // Get area from the server 53 double area = fromServer.readDouble(); 54 55 // Display to the text area 56 ta.appendText( "Radius is " + radius + "\n" ); 57 ta.appendText( "Area received from the server is " 58 + area + '\n' );

handle action event

read radius

write radius

read area

create UI

33-8 Chapter 33 Networking

60 catch (IOException ex) { 61 System.err.println(ex); 62 } 63 }); 64 65 try { 66 // Create a socket to connect to the server 67 Socket socket = new Socket( "localhost" , 8000 ); 68 // Socket socket = new Socket("130.254.204.36", 8000); 69 // Socket socket = new Socket("drake.Armstrong.edu", 8000); 70 71 // Create an input stream to receive data from the server 72 fromServer = new DataInputStream(socket.getInputStream()); 73 74 // Create an output stream to send data to the server 75 toServer = new DataOutputStream(socket.getOutputStream()); 76 } 77 catch (IOException ex) { 78 ta.appendText(ex.toString() + '\n' ); 79 } 80 } 81 }

You start the server program first then start the client program. In the client program, enter a

radius in the text field and press Enter to send the radius to the server. The server computes

the area and sends it back to the client. This process is repeated until one of the two programs

terminates.

The networking classes are in the package java.net. You should import this package

when writing Java network programs.

The Server class creates a ServerSocket serverSocket and attaches it to port 8000

using this statement (line 26 in Server.java):

ServerSocket serverSocket = new ServerSocket( 8000 );

The server then starts to listen for connection requests, using the following statement (line 31

in Server.java):

Socket socket = serverSocket.accept();

The server waits until the client requests a connection. After it is connected, the server

reads the radius from the client through an input stream, computes the area, and sends the

result to the client through an output stream. The ServerSocket accept() method takes

time to execute. It is not appropriate to run this method in the JavaFX application thread.

So, we place it in a separate thread (lines 23–59). The statements for updating GUI needs

to run from the JavaFX application thread using the Platform.runLater method (lines

The Client class uses the following statement to create a socket that will request a con-

nection to the server on the same machine (localhost) at port 8000 (line 67 in Client.java).

Socket socket = new Socket( "localhost" , 8000 );

If you run the server and the client on different machines, replace localhost with the server

machine’s host name or IP address. In this example, the server and the client are running on

the same machine.

If the server is not running, the client program terminates with a java.net.

ConnectException. After it is connected, the client gets input and output streams—wrapped

by data input and output streams—in order to receive and send data to the server.

request connection

input from server

output to server

33-10 Chapter 33 Networking

System.out.println( "Client's IP Address is " + inetAddress.getHostAddress());

You can also create an instance of InetAddress from a host name or IP address using the

static getByName method. For example, the following statement creates an InetAddress for

the host liang.armstrong.edu.

InetAddress address = InetAddress.getByName( "liang.armstrong.edu" );

Listing 33.3 gives a program that identifies the host name and IP address of the arguments you

pass in from the command line. Line 7 creates an InetAddress using the getByName method.

Lines 8 and 9 use the getHostName and getHostAddress methods to get the host’s name

and IP address. Figure 33.7 shows a sample run of the program.

Figure 33.7 The program identifies host names and IP addresses.

Listing 33.3 IdentifyHostNameIP.java 1 import java.net.*; 2 3 public class IdentifyHostNameIP { 4 public static void main(String[] args) { 5 for ( int i = 0 ; i < args.length; i++) { 6 try { 7 InetAddress address = InetAddress.getByName(args[i]); 8 System.out.print( "Host name: " + address.getHostName() + " " ); 9 System.out.println( "IP address: " + address.getHostAddress()); 10 } 11 catch (UnknownHostException ex) { 12 System.err.println( "Unknown host or IP address " + args[i]); 13 } 14 } 15 } 16 }

33.3.1 How do you obtain an instance of InetAddress? 33.3.2 What methods can you use to get the IP address and hostname from an InetAddress?

33.4 Serving Multiple Clients

A server can serve multiple clients. The connection to each client is handled by one thread.

Multiple clients are quite often connected to a single server at the same time. Typically, a

server runs continuously on a server computer, and clients from all over the Internet can con-

nect to it. You can use threads to handle the server’s multiple clients simultaneously—simply

get an InetAddress get host name get host IP

Point

Check

Point

Key

33.4 Serving Multiple Clients 33-

create a thread for each connection. Here is how the server handles the establishment of a

connection:

while ( true ) { Socket socket = serverSocket.accept(); // Connect to a client Thread thread = new ThreadClass(socket); thread.start(); }

The server socket can have many connections. Each iteration of the while loop creates a new

connection. Whenever a connection is established, a new thread is created to handle commu-

nication between the server and the new client, and this allows multiple connections to run at

the same time.

Listing 33.4 creates a server class that serves multiple clients simultaneously. For each con-

nection, the server starts a new thread. This thread continuously receives input (the radius of a

circle) from clients and sends the results (the area of the circle) back to them (see Figure 33.8).

The client program is the same as in Listing 33.2. A sample run of the server with two clients

is shown in Figure 33.9.

Figure 33.9 The server spawns a thread in order to serve a client.

Figure 33.8 Multithreading enables a server to handle multiple independent clients.

Server

Client 1... Client n

A server socket A socket for a on a port client A socket for a client

Listing 33.4 MultiThreadServer.java

1 import java.io.; 2 import java.net.; 3 import java.util.Date; 4 import javafx.application.Application; 5 import javafx.application.Platform; 6 import javafx.scene.Scene; 7 import javafx.scene.control.ScrollPane; 8 import javafx.scene.control.TextArea; 9 import javafx.stage.Stage; 10

33.5 Sending and Receiving Objects 33-

72 /** Run a thread */ 73 public void run() { 74 try { 75 // Create data input and output streams 76 DataInputStream inputFromClient = new DataInputStream( 77 socket.getInputStream()); 78 DataOutputStream outputToClient = new DataOutputStream( 79 socket.getOutputStream()); 80 81 // Continuously serve the client 82 while ( true ) { 83 // Receive radius from the client 84 double radius = inputFromClient.readDouble(); 85 86 // Compute area 87 double area = radius * radius * Math.PI; 88 89 // Send area back to the client 90 outputToClient.writeDouble(area); 91 92 Platform.runLater(() -> { 93 ta.appendText( "radius received from client: " + 94 radius + '\n' ); 95 ta.appendText( "Area found: " + area + '\n' ); 96 }); 97 } 98 } 99 catch (IOException ex) { 100 ex.printStackTrace(); 101 } 102 } 103 } 104 }

The server creates a server socket at port 8000 (line 29) and waits for a connection (line 35).

When a connection with a client is established, the server creates a new thread to handle

the communication (line 54). It then waits for another connection in an infinite while loop

(lines 33–55).

The threads, which run independently of one another, communicate with designated

clients. Each thread creates data input and output streams that receive and send data to a

client.

33.4.1 How do you make a server serve multiple clients?

33.5 Sending and Receiving Objects

A program can send and receive objects from another program.

In the preceding examples, you learned how to send and receive data of primitive types. You

can also send and receive objects using ObjectOutputStream and ObjectInputStream

on socket streams. To enable passing, the objects must be serializable. The following example

demonstrates how to send and receive objects.

The example consists of three classes: StudentAddress.java (Listing 33.5), StudentClient.java

(Listing 33.6), and StudentServer.java (Listing 33.7). The client program collects student

information from the client and sends it to a server, as shown in Figure 33.10.

The StudentAddress class contains the student information: name, street, city, state,

and zip. The StudentAddress class implements the Serializable interface. Therefore, a

StudentAddress object can be sent and received using the object output and input streams.

I/O

update GUI

Point

Check

Point

Key

33-14 Chapter 33 Networking

Listing 33.5 StudentAddress.java

1 public class StudentAddress implements java.io.Serializable { 2 private String name; 3 private String street; 4 private String city; 5 private String state; 6 private String zip; 7 8 public StudentAddress(String name, String street, String city, 9 String state, String zip) { 10 this .name = name; 11 this .street = street; 12 this .city = city; 13 this .state = state; 14 this .zip = zip; 15 } 16 17 public String getName() { 18 return name; 19 } 20 21 public String getStreet() { 22 return street; 23 } 24 25 public String getCity() { 26 return city; 27 } 28 29 public String getState() { 30 return state; 31 } 32 33 public String getZip() { 34 return zip; 35 } 36 }

The client sends a StudentAddress object through an ObjectOutputStream

on the output stream socket, and the server receives the Student object through the

ObjectInputStream on the input stream socket, as shown in Figure 33.11. The client

uses the writeObject method in the ObjectOutputStream class to send data about

a student to the server, and the server receives the student’s information using the

readObject method in the ObjectInputStream class. The server and client programs

are given in Listings 33.6 and 33.7.

serialized

Figure 33.10 The client sends the student information in an object to the server.

33-16 Chapter 33 Networking

38 HBox hBox = new HBox( 2 ); 39 pane.add(hBox, 1 , 2 ); 40 hBox.getChildren().addAll(tfCity, new Label( "State" ), tfState, 41 new Label( "Zip" ), tfZip); 42 pane.add(btRegister, 1 , 3 ); 43 GridPane.setHalignment(btRegister, HPos.RIGHT); 44 45 pane.setAlignment(Pos.CENTER); 46 tfName.setPrefColumnCount( 15 ); 47 tfStreet.setPrefColumnCount( 15 ); 48 tfCity.setPrefColumnCount( 10 ); 49 tfState.setPrefColumnCount( 2 ); 50 tfZip.setPrefColumnCount( 3 ); 51 52 btRegister.setOnAction( new ButtonListener()); 53 54 // Create a scene and place it in the stage 55 Scene scene = new Scene(pane, 450 , 200 ); 56 primaryStage.setTitle( "StudentClient" ); // Set the stage title 57 primaryStage.setScene(scene); // Place the scene in the stage 58 primaryStage.show(); // Display the stage 59 } 60 61 /** Handle button action */ 62 private class ButtonListener implements EventHandler { 63 @Override 64 public void handle(ActionEvent e) { 65 try { 66 // Establish connection with the server 67 Socket socket = new Socket(host, 8000 ); 68 69 // Create an output stream to the server 70 ObjectOutputStream toServer = 71 new ObjectOutputStream(socket.getOutputStream()); 72 73 // Get text field 74 String name = tfName.getText().trim(); 75 String street = tfStreet.getText().trim(); 76 String city = tfCity.getText().trim(); 77 String state = tfState.getText().trim(); 78 String zip = tfZip.getText().trim(); 79 80 // Create a Student object and send to the server 81 StudentAddress s = 82 new StudentAddress(name, street, city, state, zip); 83 toServer.writeObject(s); 84 } 85 catch (IOException ex) { 86 ex.printStackTrace(); 87 } 88 } 89 } 90 }

Listing 33.7 StudentServer.java

1 import java.io.; 2 import java.net.; 3 4 public class StudentServer {

register listener

server socket

output stream

send to server

33.5 Sending and Receiving Objects 33-

5 private ObjectOutputStream outputToFile; 6 private ObjectInputStream inputFromClient; 7 8 public static void main(String[] args) { 9 new StudentServer(); 10 } 11 12 public StudentServer() { 13 try { 14 // Create a server socket 15 ServerSocket serverSocket = new ServerSocket( 8000 ); 16 System.out.println( "Server started " ); 17 18 // Create an object output stream 19 outputToFile = new ObjectOutputStream( 20 new FileOutputStream( "student.dat" , true )); 21 22 while ( true ) { 23 // Listen for a new connection request 24 Socket socket = serverSocket.accept(); 25 26 // Create an input stream from the socket 27 inputFromClient = 28 new ObjectInputStream(socket.getInputStream()); 29 30 // Read from input 31 Object object = inputFromClient.readObject(); 32 33 // Write to the file 34 outputToFile.writeObject(object); 35 System.out.println( "A new student object is stored" ); 36 } 37 } 38 catch (ClassNotFoundException ex) { 39 ex.printStackTrace(); 40 } 41 catch (IOException ex) { 42 ex.printStackTrace(); 43 } 44 finally { 45 try { 46 inputFromClient.close(); 47 outputToFile.close(); 48 } 49 catch (Exception ex) { 50 ex.printStackTrace(); 51 } 52 } 53 } 54 }

On the client side, when the user clicks the Register to the Server button, the client creates

a socket to connect to the host (line 67), creates an ObjectOutputStream on the output

stream of the socket (lines 70 and 71), and invokes the writeObject method to send the

StudentAddress object to the server through the object output stream (line 83).

On the server side, when a client connects to the server, the server creates an

Object InputStream on the input stream of the socket (lines 27 and 28), invokes the

readObject method to receive the StudentAddress object through the object input

stream (line 31), and writes the object to a file (line 34).

server socket

output to file

connect to client

input stream

get from client

write to file

33.6 Case Study: Distributed Tic-Tac-Toe Games 33-

■ ■ TicTacToeClient models a player in Listing 33.10.

■ ■ Cell models a cell in the game. It is an inner class in TicTacToeClient.

■ ■ TicTacToeConstants is an interface that defines the constants shared by all the

classes in the example in Listing 33.8.

The relationships of these classes are shown in Figure 33.14.

Listing 33.8 TicTacToeConstants.java

1 public interface TicTacToeConstants { 2 public static int PLAYER1 = 1 ; // Indicate player 1 3 public static int PLAYER2 = 2 ; // Indicate player 2 4 public static int PLAYER1_WON = 1 ; // Indicate player 1 won 5 public static int PLAYER2_WON = 2 ; // Indicate player 2 won 6 public static int DRAW = 3 ; // Indicate a draw 7 public static int CONTINUE = 4 ; // Indicate to continue 8 }

Listing 33.9 TicTacToeServer.java

1 import java.io.; 2 import java.net.;

Figure 33.13 The server starts a thread to facilitate communications between the two players.

Player 1

  1. Initialize user interface.
  2. Request connection to the server and learn which token to use from the server.
  3. Get the start signal from the server.
  4. Wait for the player to mark a cell, send the cell's row and column index to the server.
  5. Receive status from the server.
  6. If WIN, display the winner; if Player 2 wins, receive the last move from Player 2. Break the loop.
  7. If DRAW, display game is over; break the loop.
  8. If CONTINUE, receive Player 2's selected row and column index and mark the cell for Player 2.

Server

Create a server socket.

Accept connection from the first player and notify the player who is Player 1 with token X.

Accept connection from the second player and notify the player who is Player 2 with token O. Start a thread for the session.

Player 2

  1. Initialize user interface.

  2. Request connection to the server and learn which token to use from the server.

  3. Receive status from the server.

  4. If WIN, display the winner. If Player 1 wins, receive Player 1's last move, and break the loop.

  5. If DRAW, display game is over , and receive Player 1's last move, and break the loop.

  6. If CONTINUE, receive Player 1's selected row and index and mark the cell for Player 1.

  7. Wait for the player to move, and send the selected row and column to the server.

Handle a session:

  1. Tell Player 1 to start.

  2. Receive row and column of the selected cell from Player 1.

  3. Determine the game status (WIN, DRAW, CONTINUE). If Player 1 wins, or draws, send the status (PLAYER1_WON, DRAW) to both players and send Player 1's move to Player 2. Exit.

  4. If CONTINUE, notify Player 2 to take the turn, and send Player 1's newly selected row and column index to Player 2.

  5. Receive row and column of the selected cell from Player 2.

  6. If Player 2 wins, send the status (PLAYER2_WON) to both players, and send Player 2's move to Player 1. Exit.

  7. If CONTINUE, send the status, and send Player 2's newly selected row and column index to Player 1.

33-20 Chapter 33 Networking

3 import java.util.Date; 4 import javafx.application.Application; 5 import javafx.application.Platform; 6 import javafx.scene.Scene; 7 import javafx.scene.control.ScrollPane; 8 import javafx.scene.control.TextArea; 9 import javafx.stage.Stage; 10 11 public class TicTacToeServer extends Application 12 implements TicTacToeConstants { 13 private int sessionNo = 1 ; // Number a session 14 15 @Override // Override the start method in the Application class 16 public void start(Stage primaryStage) { 17 TextArea taLog = new TextArea(); 18 19 // Create a scene and place it in the stage 20 Scene scene = new Scene( new ScrollPane(taLog), 450 , 200 ); 21 primaryStage.setTitle( "TicTacToeServer" ); // Set the stage title 22 primaryStage.setScene(scene); // Place the scene in the stage 23 primaryStage.show(); // Display the stage 24 25 new Thread( () -> { 26 try { 27 // Create a server socket

create UI

Figure 33.14 TicTacToeServer creates an instance of HandleASession for each session of two players.

TicTacToeClient creates nine cells in the UI.

TicTacToeConstants

Runnable

TicTacToeServer

JApplet TicTacToeClient Cell

JFrame

Similar to Listing 18.

TicTacToeServer

+PLAYER1 = 1: int +PLAYER2 = 2: int +PLAYER1_WON = 1: int +PLAYER2_WON = 2: int +DRAW = 3: int +CONTINUE = 4: int

HandleASession TicTacToeClient

-player1: Socket -player2: Socket -cell: char[][] -continueToPlay: boolean

+run(): void -isWon(): boolean -isFull(): boolean -sendMove(out: DataOutputStream, row: int, column: int): void

-myTurn: boolean -myToken: char -otherToken: char -cell: Cell[][] -continueToPlay: boolean -rowSelected: int -columnSelected: int -fromServer: DataInputStream -toServer: DataOutputStream -waiting: boolean

+run(): void -connectToServer(): void -receiveMove(): void -sendMove(): void -receiveInfoFromServer(): void -waitForPlayerAction(): void

HandleASession

«interface» TicTacToeConstants

+main(args: String[]):void