Csphtp1 22
-
Upload
hust -
Category
Technology
-
view
356 -
download
1
description
Transcript of Csphtp1 22
2002 Prentice Hall. All rights reserved.
1
Chapter 22 – Networking: Streams-Based Sockets and Datagrams
Outline22.1 Introduction22.2 Establishing a Simple Server (Using Stream Sockets)22.3 Establishing a Simple Client (Using Stream Sockets)22.4 Client/Server Interaction with Stream-Socket Connections22.5 Connectionless Client/Server Interaction with Datagrams22.6 Client/Server Tic-Tac-Toe Using a Multithreaded Server
2002 Prentice Hall. All rights reserved.
2
22.1 Introduction
• Information system– The Internet
• Networking technologies– Client-server relationship
– Socket-based communications• Stream sockets
– Packet-based communications• Datagram sockets
2002 Prentice Hall. All rights reserved.
3
22.2 Establishing a Simple Server (Using Stream Sockets)
• Five step process:– Create an object of TcpListener
• Binds server to port number
– Call Start method• Begin connection request
– Make connection between server and client• Returns a Socket object
– Processing phase• Methods Receive and Send
– Connection-termination phase• Method Close
– Multithreaded servers
2002 Prentice Hall. All rights reserved.
4
22.3 Establishing a Simple Client (Using Stream Sockets)
• Four step process:– Create object of TcpClient
• Method Connect
– Get a NetworkStream• WriteByte and ReadByte
– Processing phase• Client and server communicate
– Close connection• Method Close
2002 Prentice Hall. All rights reserved.
522.4 Client/Server Interaction with Steam-
Socket Connections• Client/server application
– Client request connection
– Server application sends array of bytes
– Communicate visually via TextBoxes
2002 Prentice Hall.All rights reserved.
Outline6
Server.cs
1 // Fig. 22.1: Server.cs2 // Set up a Server that will receive a connection from a client,3 // send a string to the client, and close the connection.4 5 using System;6 using System.Drawing;7 using System.Collections;8 using System.ComponentModel;9 using System.Windows.Forms;10 using System.Threading;11 using System.Net.Sockets;12 using System.IO;13 14 // server that awaits client connections (one at a time) and15 // allows a conversation between client and server16 public class Server : System.Windows.Forms.Form17 {18 private System.Windows.Forms.TextBox inputTextBox;19 private System.Windows.Forms.TextBox displayTextBox;20 private Socket connection;21 private Thread readThread;22 23 private System.ComponentModel.Container components = null;24 private NetworkStream socketStream;25 private BinaryWriter writer;26 private BinaryReader reader;27 28 // default constructor29 public Server()30 {31 InitializeComponent();32
2002 Prentice Hall.All rights reserved.
Outline7
Server.cs
33 // create a new thread from the server34 readThread = new Thread( new ThreadStart( RunServer ) );35 readThread.Start();36 }37 38 // Visual Studio .NET generated code39 40 [STAThread]41 static void Main() 42 {43 Application.Run( new Server() );44 }45 46 protected void Server_Closing( 47 object sender, CancelEventArgs e )48 { 49 System.Environment.Exit( System.Environment.ExitCode );50 }51 52 // sends the text typed at the server to the client53 protected void inputTextBox_KeyDown( 54 object sender, KeyEventArgs e )55 {56 // sends the text to the client57 try58 { 59 if ( e.KeyCode == Keys.Enter && connection != null )60 {61 writer.Write( "SERVER>>> " + inputTextBox.Text );62 63 displayTextBox.Text += 64 "\r\nSERVER>>> " + inputTextBox.Text;65
Thread will accept connections from clients
Will invoke method RunServer
Read strings and send via method Write
Terminate all threads
Method Exit closes all thread associated with application
2002 Prentice Hall.All rights reserved.
Outline8
Server.cs
66 // if the user at the server signaled termination67 // sever the connection to the client68 if ( inputTextBox.Text == "TERMINATE" )69 connection.Close();70 71 inputTextBox.Clear();72 }73 }74 catch ( SocketException )75 {76 displayTextBox.Text += "\nError writing object";77 }78 } // inputTextBox_KeyDown79 80 // allows a client to connect and displays the text it sends81 public void RunServer()82 {83 TcpListener listener;84 int counter = 1;85 86 // wait for a client connection and display the text87 // that the client sends88 try89 {90 // Step 1: create TcpListener91 listener = new TcpListener( 5000 );92 93 // Step 2: TcpListener waits for connection request94 listener.Start();95 96 // Step 3: establish connection upon client request97 while ( true )98 {99 displayTextBox.Text = "Waiting for connection\r\n";100
TcpListener to pick request from user at port 5000
Gets TcpListener to begin waiting for requests
Infinite loop to establish connection request by clients
2002 Prentice Hall.All rights reserved.
Outline9
Server.cs
101 // accept an incoming connection102 connection = listener.AcceptSocket();103 104 // create NetworkStream object associated with socket105 socketStream = new NetworkStream( connection );106 107 // create objects for transferring data across stream108 writer = new BinaryWriter( socketStream );109 reader = new BinaryReader( socketStream );110 111 displayTextBox.Text += "Connection " + counter +112 " received.\r\n";113 114 // inform client that connection was successfull115 writer.Write( "SERVER>>> Connection successful" );116 117 inputTextBox.ReadOnly = false;118 string theReply = "";119 120 // Step 4: read String data sent from client121 do122 {123 try124 { 125 // read the string sent to the server126 theReply = reader.ReadString();127 128 // display the message129 displayTextBox.Text += "\r\n" + theReply;130 }131
Returns a Socket upon successful connection
Pass the new socket as argument to NetworkStream
For use with writing or reading data
Indicate that a connection was received
Execute until server receive connection termination
2002 Prentice Hall.All rights reserved.
Outline10
Server.cs
132 // handle exception if error reading data133 catch ( Exception )134 {135 break;136 }137 138 } while ( theReply != "CLIENT>>> TERMINATE" &&139 connection.Connected );140 141 displayTextBox.Text += 142 "\r\nUser terminated connection";143 144 // Step 5: close connection145 inputTextBox.ReadOnly = true;146 writer.Close();147 reader.Close();148 socketStream.Close();149 connection.Close();150 151 ++counter;152 }153 } // end try154 155 catch ( Exception error )156 {157 MessageBox.Show( error.ToString() );158 }159 160 } // end method RunServer161 162 } // end class Server
Close connection between client and server and waits for next request
2002 Prentice Hall.All rights reserved.
Outline11
Client.cs
1 // Fig. 22.2: Client.cs2 // Set up a Client that will read information sent from a Server3 // and display the information.4 5 using System;6 using System.Drawing;7 using System.Collections;8 using System.ComponentModel;9 using System.Windows.Forms;10 using System.Threading;11 using System.Net.Sockets;12 using System.IO;13 14 // connects to a chat server15 public class Client : System.Windows.Forms.Form16 {17 private System.Windows.Forms.TextBox inputTextBox;18 private System.Windows.Forms.TextBox displayTextBox;19 20 private NetworkStream output;21 private BinaryWriter writer;22 private BinaryReader reader;23 24 private string message = "";25 26 private Thread readThread;27 28 private System.ComponentModel.Container components = null;29
2002 Prentice Hall.All rights reserved.
Outline12
Client.cs
30 // default constructor31 public Client()32 {33 InitializeComponent();34 35 readThread = new Thread( new ThreadStart( RunClient ) );36 readThread.Start();37 }38 39 // Visual Studio .NET-generated code 40 41 [STAThread]42 static void Main() 43 {44 Application.Run( new Client() );45 }46 47 protected void Client_Closing( 48 object sender, CancelEventArgs e )49 { 50 System.Environment.Exit( System.Environment.ExitCode );51 }52 53 // sends text the user typed to server54 protected void inputTextBox_KeyDown ( 55 object sender, KeyEventArgs e )56 {57 try58 { 59 if ( e.KeyCode == Keys.Enter )60 {61 writer.Write( "CLIENT>>> " + inputTextBox.Text );62
Like Server object, Client object creates Thread to handling incoming messages
2002 Prentice Hall.All rights reserved.
Outline13
Client.cs
63 displayTextBox.Text += 64 "\r\nCLIENT>>> " + inputTextBox.Text;65 66 inputTextBox.Clear(); 67 }68 }69 catch ( SocketException ioe )70 {71 displayTextBox.Text += "\nError writing object";72 }73 74 } // end method inputTextBox_KeyDown75 76 // connect to server and display server-generated text77 public void RunClient()78 {79 TcpClient client;80 81 // instantiate TcpClient for sending data to server82 try83 { 84 displayTextBox.Text += "Attempting connection\r\n";85 86 // Step 1: create TcpClient and connect to server87 client = new TcpClient();88 client.Connect( "localhost", 5000 );89 90 // Step 2: get NetworkStream associated with TcpClient91 output = client.GetStream();92 93 // create objects for writing and reading across stream94 writer = new BinaryWriter( output );95 reader = new BinaryReader( output );96
Method to connect and receive data from the Server and send data to the Server
Method Connect used to establish connection
First argument is name of the server
Also considered the loopback IP address
Port number must match port number set for connection on server
2002 Prentice Hall.All rights reserved.
Outline14
Client.cs
97 displayTextBox.Text += "\r\nGot I/O streams\r\n";98 99 inputTextBox.ReadOnly = false;100 101 // loop until server signals termination102 do103 {104 105 // Step 3: processing phase106 try107 {108 // read message from server109 message = reader.ReadString();110 displayTextBox.Text += "\r\n" + message; 111 }112 113 // handle exception if error in reading server data114 catch ( Exception )115 {116 System.Environment.Exit( 117 System.Environment.ExitCode );118 }119 } while( message != "SERVER>>> TERMINATE" );120 121 displayTextBox.Text += "\r\nClosing connection.\r\n";122 123 // Step 4: close connection124 writer.Close();125 reader.Close();126 output.Close();127 client.Close();128 Application.Exit();129 }130
Loop until client receive connection-terminate message
To obtain next message from the server
2002 Prentice Hall.All rights reserved.
Outline15
Client.cs
131 // handle exception if error in establishing connection132 catch ( Exception error )133 {134 MessageBox.Show( error.ToString() );135 }136 137 } // end method RunClient138 139 } // end class Client
2002 Prentice Hall.All rights reserved.
Outline16
Client.cs Program Output
2002 Prentice Hall.All rights reserved.
Outline17
Client.cs Program Output
2002 Prentice Hall. All rights reserved.
18
22.5 Connectionless Client/Server Interaction with Datagram
• Resembles postal services– Bundles and sends information in packets
2002 Prentice Hall.All rights reserved.
Outline19
Server.cs
1 // Fig. 22.3: Server.cs2 // Set up a Server that will receive packets from a3 // client and send packets to a client.4 5 using System;6 using System.Drawing;7 using System.Collections;8 using System.ComponentModel;9 using System.Windows.Forms;10 using System.Data;11 using System.Net;12 using System.Net.Sockets;13 using System.Threading;14 15 // create the UDP server16 public class Server : System.Windows.Forms.Form17 {18 private System.Windows.Forms.TextBox displayTextBox;19 private UdpClient client;20 private IPEndPoint receivePoint;21 private System.ComponentModel.Container components = null;22 23 // no-argument constructor24 public Server()25 {26 InitializeComponent();27 28 client = new UdpClient( 5000 );29 receivePoint = new IPEndPoint( new IPAddress( 0 ), 0 );30 Thread readThread = new Thread( 31 new ThreadStart( WaitForPackets ) );32
Creates an instance of UdpClient class to receive data at port 5000Instance of class IPEndPoint to hold IP address and port number of clientIPAddress object
Port number of the endpoint
2002 Prentice Hall.All rights reserved.
Outline20
Server.cs
33 readThread.Start(); 34 }35 36 // Visual Studio .NET generated code37 38 [STAThread]39 static void Main() 40 {41 Application.Run( new Server() );42 }43 44 // shut down the server45 protected void Server_Closing( 46 object sender, CancelEventArgs e )47 {48 System.Environment.Exit( System.Environment.ExitCode );49 }50 51 // wait for a packet to arrive52 public void WaitForPackets()53 {54 while ( true )55 {56 // receive byte array from client 57 byte[] data = client.Receive( ref receivePoint );58 59 // output packet data to TextBox60 displayTextBox.Text += "\r\nPacket received:" +61 "\r\nLength: " + data.Length + "\r\nContaining: " + 62 System.Text.Encoding.ASCII.GetString( data );63
Infinite loop wait for data to arrive at the Server
Method Receive gets a byte array from the client
Update Server’s display to include packet’s information and content
2002 Prentice Hall.All rights reserved.
Outline21
Server.cs
64 displayTextBox.Text += 65 "\r\n\r\nEcho data back to client...";66 67 // echo information from packet back to client68 client.Send( data, data.Length, receivePoint );69 displayTextBox.Text += "\r\nPacket sent\r\n";70 }71 72 } // end method WaitForPackets73 74 } // end class Server
Echo data back to the client
Method Send takes three argumentThe byte array to sendThe array’s length
IPEndPoint to send the data
recievePoint store IP address and port number of sender
2002 Prentice Hall.All rights reserved.
Outline22
Server.cs Program Output
2002 Prentice Hall.All rights reserved.
Outline23
Client.cs
1 // Fig. 22.4: Client.cs2 // Set up a Client that sends packets to a server and receives 3 // packets from a server.4 5 using System;6 using System.Drawing;7 using System.Collections;8 using System.ComponentModel;9 using System.Windows.Forms;10 using System.Data;11 using System.Net;12 using System.Net.Sockets;13 using System.Threading;14 15 // run the UDP client16 public class Client : System.Windows.Forms.Form17 {18 private System.Windows.Forms.TextBox inputTextBox;19 private System.Windows.Forms.TextBox displayTextBox;20 21 private UdpClient client; 22 private IPEndPoint receivePoint;23 24 private System.ComponentModel.Container components = null;25 26 // no-argument constructor27 public Client()28 {29 InitializeComponent();30
2002 Prentice Hall.All rights reserved.
Outline24
Client.cs
31 receivePoint = new IPEndPoint( new IPAddress( 0 ), 0 );32 client = new UdpClient( 5001 );33 Thread thread = 34 new Thread( new ThreadStart( WaitForPackets ) );35 thread.Start();36 }37 38 // Visual Studio.NET generated code39 40 [STAThread]41 static void Main()42 {43 Application.Run( new Client() );44 }45 46 // shut down the client47 protected void Client_Closing( 48 object sender, CancelEventArgs e )49 {50 System.Environment.Exit( System.Environment.ExitCode );51 }52 53 // send a packet54 protected void inputTextBox_KeyDown( 55 object sender, KeyEventArgs e )56 {57 if ( e.KeyCode == Keys.Enter )58 {59 // create packet (datagram) as string60 string packet = inputTextBox.Text;61 displayTextBox.Text += 62 "\r\nSending packet containing: " + packet;63
Instantiate a UdpClient object with port 5001
2002 Prentice Hall.All rights reserved.
Outline25
Client.cs
64 // convert packet to byte array65 byte[] data = 66 System.Text.Encoding.ASCII.GetBytes( packet );67 68 // send packet to server on port 500069 client.Send( data, data.Length, "localhost", 5000 );70 displayTextBox.Text += "\r\nPacket sent\r\n";71 inputTextBox.Clear();72 }73 } // end method inputTextBox_KeyDown74 75 // wait for packets to arrive76 public void WaitForPackets()77 {78 while ( true )79 {80 // receive byte array from server81 byte[] data = client.Receive( ref receivePoint );82 83 // output packet data to TextBox84 displayTextBox.Text += "\r\nPacket received:" +85 "\r\nLength: " + data.Length + "\r\nContaining: " + 86 System.Text.Encoding.ASCII.GetString( data ) + 87 "\r\n";88 }89 90 } // end method WaitForPackets91 92 } // end class Client
Convert the string that user entered in TextBox to a byte arrayUdpClient method Send to
send byte array to the Server
Port 5000 is the Server’s port
Infinite loop to wait for the packets
Receive blocks until a packet is received
Method WaitForPacket is run on a separate thread
2002 Prentice Hall.All rights reserved.
Outline26
Client.cs
Program Output
The Client window before sending a packet to the server
The Client window after sending a packet to the server and receiving the packet back from the server
2002 Prentice Hall. All rights reserved.
27
22.6 Client/Server Tic-Tac-Toe Using a Multithreaded Server
• Game of tic-tac-toe– Implemented with stream sockets
– First person to connect is player ‘X’
2002 Prentice Hall.All rights reserved.
Outline28
Server.cs
1 // Fig. 22.5: Server.cs2 // This class maintains a game of Tic-Tac-Toe for two3 // client applications.4 5 using System;6 using System.Drawing;7 using System.Collections;8 using System.ComponentModel;9 using System.Windows.Forms;10 using System.Data;11 using System.Net.Sockets;12 using System.Threading;13 using System.IO;14 15 // awaits connections from two clients and allows them to16 // play tic-tac-toe against each other17 public class Server : System.Windows.Forms.Form18 {19 private System.Windows.Forms.TextBox displayTextBox;20 21 private byte[] board;22 23 private Player[] players;24 private Thread[] playerThreads;25 26 private TcpListener listener;27 private int currentPlayer;28 private Thread getPlayers;29 30 private System.ComponentModel.Container components = null;31 32 internal bool disconnected = false;33
2002 Prentice Hall.All rights reserved.
Outline29
Server.cs
34 // default constructor35 public Server()36 {37 InitializeComponent();38 39 board = new byte[ 9 ];40 41 players = new Player[ 2 ];42 playerThreads = new Thread[ 2 ];43 currentPlayer = 0;44 45 // accept connections on a different thread46 getPlayers = new Thread( new ThreadStart( SetUp ) );47 getPlayers.Start(); 48 }49 50 // Visual Studio .NET-generated code51 52 [STAThread]53 static void Main() 54 {55 Application.Run( new Server() );56 }57 58 protected void Server_Closing(59 object sender, CancelEventArgs e )60 {61 disconnected = true;62 }63
Create array to store player’s moves
Correspond to the first player, ‘X’
Server uses to accept connections so that current Thread does not block while awaiting players
2002 Prentice Hall.All rights reserved.
Outline30
Server.cs
64 // accepts connections from 2 players65 public void SetUp()66 {67 // set up Socket68 listener = new TcpListener( 5000 );69 listener.Start();70 71 // accept first player and start a thread for him or her72 players[ 0 ] = 73 new Player( listener.AcceptSocket(), this, 0 );74 playerThreads[ 0 ] = new Thread( 75 new ThreadStart( players[ 0 ].Run ) );76 playerThreads[ 0 ].Start();77 78 // accept second player and start a thread for him or her79 players[ 1 ] = 80 new Player( listener.AcceptSocket(), this, 1 );81 playerThreads[ 1 ] = 82 new Thread( new ThreadStart( players[ 1 ].Run ) );83 playerThreads[ 1 ].Start();84 85 // let the first player know that the other player has86 // connected87 lock ( players[ 0 ] )88 {89 players[ 0 ].threadSuspended = false;90 Monitor.Pulse( players[ 0 ] );91 }92 } // end method SetUp93 94 // appends the argument to text in displayTextBox95 public void Display( string message )96 {97 displayTextBox.Text += message + "\r\n";98 }
Create TcpListener to listen for request on port 5000
Instantiate Player object representing the player
Thread that execute Run methods of Player object
Server notifies Player of connection by setting Player’s threadSuspend variable to false
2002 Prentice Hall.All rights reserved.
Outline31
Server.cs
99 100 // determine if a move is valid101 public bool ValidMove( int location, int player )102 {103 // prevent another thread from making a move104 lock ( this )105 {106 // while it is not the current player's turn, wait107 while ( player != currentPlayer )108 Monitor.Wait( this );109 110 // if the desired square is not occupied111 if ( !IsOccupied( location ) )112 {113 // set the board to contain the current player's mark114 board[ location ] = ( byte ) ( currentPlayer == 0 ? 115 'X' : 'O' );116 117 // set the currentPlayer to be the other player118 currentPlayer = ( currentPlayer + 1 ) % 2;119 120 // notify the other player of the move121 players[ currentPlayer ].OtherPlayerMoved( location );122 123 // alert the other player it's time to move124 Monitor.Pulse( this );125 126 return true;127 }128 else129 return false;130 }131 } // end method ValidMove132
Method will send to client message indicating whether the move was valid
lock statement ensure that only one move could be made
Return false if location already contain a mark
Place mark on the local representation of the board
Notify that a move has been made
2002 Prentice Hall.All rights reserved.
Outline32
Server.cs
133 // determines whether the specified square is occupied134 public bool IsOccupied( int location )135 {136 if ( board[ location ] == 'X' || board[ location ] == 'O' )137 return true;138 else139 return false;140 }141 142 // determines if the game is over143 public bool GameOver()144 {145 // place code here to test for a winner of the game146 return false;147 }148 149 } // end class Server150 151 public class Player152 {153 internal Socket connection;154 private NetworkStream socketStream;155 private Server server;156 private BinaryWriter writer;157 private BinaryReader reader;158 159 private int number;160 private char mark;161 internal bool threadSuspended = true;162 163 // constructor requiring Socket, Server and int objects164 // as arguments165 public Player( Socket socket, Server serverValue, int newNumber )166 {
Player constructorReference to the Socket object Reference to Server object
Contain the mark used by the player
2002 Prentice Hall.All rights reserved.
Outline33
Server.cs
167 mark = ( newNumber == 0 ? 'X' : 'O' );168 169 connection = socket;170 171 server = serverValue;172 number = newNumber;173 174 // create NetworkStream object for Socket175 socketStream = new NetworkStream( connection );176 177 // create Streams for reading/writing bytes178 writer = new BinaryWriter( socketStream );179 reader = new BinaryReader( socketStream );180 181 } // end constructor182 183 // signal other player of move184 public void OtherPlayerMoved( int location )185 {186 // signal that opponent moved187 writer.Write( "Opponent moved" );188 writer.Write( location ); // send location of move189 }190 191 // allows the players to make moves and receives moves192 // from other player193 public void Run()194 {195 bool done = false;196 197 // display on the server that a connection was made198 server.Display( "Player " + ( number == 0 ? 'X' : 'O' )199 + " connected" );200
Server calls method Run after instantiating a Player object
Notify that the connection was successful
2002 Prentice Hall.All rights reserved.
Outline34
Server.cs
201 // send the current player's mark to the server202 writer.Write( mark );203 204 // if number equals 0 then this player is X, so send205 writer.Write( "Player " + ( number == 0 ? 206 "X connected\r\n" : "O connected, please wait\r\n" ) );207 208 // wait for another player to arrive209 if ( mark == 'X' )210 {211 writer.Write( "Waiting for another player" );212 213 // wait for notification from server that another 214 // player has connected215 lock ( this )216 {217 while ( threadSuspended )218 Monitor.Wait( this );219 }220 221 writer.Write( "Other player connected. Your move" );222 223 } // end if224 225 // play game226 while ( !done )227 { 228 // wait for data to become available229 while ( connection.Available == 0 )230 {231 Thread.Sleep( 1000 );232 233 if ( server.disconnected )234 return; 235 }
Report which char client will be placing on the board
Must wait for second player to join
Suspend thread for player ‘X’ until player ‘O’ is connected
When threadSuspended becomes false, Player exits while loop
Enable user to play the game
Run loop until Socket property Available indicates information from Socket
If no information, thread goes to sleepCheck whether server
variable is trueIf true, Thread exits the method
2002 Prentice Hall.All rights reserved.
Outline35
Server.cs
236 237 // receive data238 int location = reader.ReadInt32();239 240 // if the move is valid, display the move on the241 // server and signal the move is valid242 if ( server.ValidMove( location, number ) )243 {244 server.Display( "loc: " + location );245 writer.Write( "Valid move." );246 }247 248 // signal the move is invalid249 else250 writer.Write( "Invalid move, try again" );251 252 // if game is over, set done to true to exit while loop253 if ( server.GameOver() )254 done = true;255 256 } // end while loop257 258 // close the socket connection259 writer.Close();260 reader.Close();261 socketStream.Close();262 connection.Close();263 264 } // end method Run265 266 } // end class Player
To read int containing location user wants to place a mark
Passes the int to Server method ValidMove
If valid, then place the mark
2002 Prentice Hall.All rights reserved.
Outline36
Client.cs
1 // Fig. 22.6: Client.cs2 // Client for the TicTacToe program.3 4 using System;5 using System.Drawing;6 using System.Collections;7 using System.ComponentModel;8 using System.Windows.Forms;9 using System.Data;10 using System.Net.Sockets;11 using System.Threading;12 using System.IO;13 14 // represents a tic-tac-toe player15 public class Client : System.Windows.Forms.Form16 {17 private System.Windows.Forms.Label idLabel;18 19 private System.Windows.Forms.TextBox displayTextBox;20 21 private System.Windows.Forms.Panel panel1;22 private System.Windows.Forms.Panel panel2;23 private System.Windows.Forms.Panel panel3;24 private System.Windows.Forms.Panel panel5;25 private System.Windows.Forms.Panel panel6;26 private System.Windows.Forms.Panel panel4;27 private System.Windows.Forms.Panel panel7;28 private System.Windows.Forms.Panel panel8;29 private System.Windows.Forms.Panel panel9;30 31 private Square[ , ] board;32 private Square currentSquare;33 34 private Thread outputThread;35
Board created out of nine Square objects
2002 Prentice Hall.All rights reserved.
Outline37
Client.cs
36 private TcpClient connection;37 private NetworkStream stream;38 private BinaryWriter writer;39 private BinaryReader reader;40 41 private char myMark;42 private bool myTurn;43 44 private SolidBrush brush;45 private System.ComponentModel.Container components = null;46 47 bool done = false;48 49 // default constructor50 public Client()51 {52 InitializeComponent();53 54 board = new Square[ 3, 3 ];55 56 // create 9 Square objects and place them on the board57 board[ 0, 0 ] = new Square( panel1, ' ', 0 );58 board[ 0, 1 ] = new Square( panel2, ' ', 1 );59 board[ 0, 2 ] = new Square( panel3, ' ', 2 );60 board[ 1, 0 ] = new Square( panel4, ' ', 3 );61 board[ 1, 1 ] = new Square( panel5, ' ', 4 );62 board[ 1, 2 ] = new Square( panel6, ' ', 5 );63 board[ 2, 0 ] = new Square( panel7, ' ', 6 );64 board[ 2, 1 ] = new Square( panel8, ' ', 7 );65 board[ 2, 2 ] = new Square( panel9, ' ', 8 );66 67 // create a SolidBrush for writing on the Squares68 brush = new SolidBrush( Color.Black );69
2002 Prentice Hall.All rights reserved.
Outline38
Client.cs
70 // Make connection to sever and get the associated 71 // network stream. Start separate thread to allow this72 // program to continually update its output in textbox.73 connection = new TcpClient( "localhost", 5000 );74 stream = connection.GetStream();75 76 writer = new BinaryWriter( stream );77 reader = new BinaryReader( stream );78 79 // start a new thread for sending and receiving messages80 outputThread = new Thread( new ThreadStart( Run ) );81 outputThread.Start();82 } // end Client constructor83 84 // Visual Studio .NET-generated code85 86 [STAThread]87 static void Main() 88 {89 Application.Run( new Client() );90 }91 92 protected void Client_Paint (93 object sender, System.Windows.Forms.PaintEventArgs e )94 {95 PaintSquares();96 }97 98 protected void Client_Closing(99 object sender, CancelEventArgs e )100 {101 done = true;102 }103
Open connection to server
Obtain reference to the connection’s associated NetworkStream objectThread to read messages sent from the server to the client
2002 Prentice Hall.All rights reserved.
Outline39
Client.cs
104 // draws the mark of each square105 public void PaintSquares()106 {107 Graphics g;108 109 // draw the appropriate mark on each panel110 for ( int row = 0; row < 3; row++ )111 for ( int column = 0; column < 3; column++ )112 {113 // get the Graphics for each Panel114 g = board[ row, column ].SquarePanel.CreateGraphics();115 116 // draw the appropriate letter on the panel117 g.DrawString( board[ row, column ].Mark.ToString(), 118 this.Font, brush, 8, 8 );119 }120 } // end method PaintSquares121 122 // send location of the clicked square to server123 protected void square_MouseUp( 124 object sender, System.Windows.Forms.MouseEventArgs e )125 {126 // for each square check if that square was clicked127 for ( int row = 0; row < 3; row++ )128 for ( int column = 0; column < 3; column++ )129 if ( board[ row, column ].SquarePanel == sender )130 {131 CurrentSquare = board[ row, column ];132 133 // send the move to the server134 SendClickedSquare( board[ row, column ].Location );135 }136 } // end method square_MouseUp137
2002 Prentice Hall.All rights reserved.
Outline40
Client.cs
138 // control thread that allows continuous update of the139 // textbox display140 public void Run()141 {142 // first get players's mark (X or O)143 myMark = reader.ReadChar();144 idLabel.Text = "You are player \"" + myMark + "\"";145 myTurn = ( myMark == 'X' ? true : false );146 147 // process incoming messages148 try149 {150 // receive messages sent to client151 while ( true )152 ProcessMessage( reader.ReadString() );153 }154 catch ( EndOfStreamException )155 {156 MessageBox.Show( "Server is down, game over", "Error",157 MessageBoxButtons.OK, MessageBoxIcon.Error );158 }159 160 } // end method Run161 162 // process messages sent to client163 public void ProcessMessage( string message )164 {165 // if the move player sent to the server is valid166 // update the display, set that square's mark to be167 // the mark of the current player and repaint the board168 if ( message == "Valid move." )169 {170 displayTextBox.Text += 171 "Valid move, please wait.\r\n";
If message indicate move to be valid, client sets mark on current square
2002 Prentice Hall.All rights reserved.
Outline41
Client.cs
172 currentSquare.Mark = myMark;173 PaintSquares();174 }175 176 // if the move is invalid, display that and it is now177 // this player's turn again178 else if ( message == "Invalid move, try again" )179 {180 displayTextBox.Text += message + "\r\n";181 myTurn = true;182 }183 184 // if opponent moved185 else if ( message == "Opponent moved" )186 {187 // find location of their move188 int location = reader.ReadInt32();189 190 // set that square to have the opponents mark and191 // repaint the board192 board[ location / 3, location % 3 ].Mark =193 ( myMark == 'X' ? 'O' : 'X' );194 PaintSquares();195 196 displayTextBox.Text += 197 "Opponent moved. Your turn.\r\n";198 199 // it is now this player's turn200 myTurn = true;201 }202
Repaint the square to accommodate the changes
Move invalid, tell user to pick another one
Indicate opponent made a move
Read from server an int specifying location
2002 Prentice Hall.All rights reserved.
Outline42
Client.cs
203 // display the message204 else205 displayTextBox.Text += message + "\r\n";206 207 } // end method ProcessMessage208 209 // sends the server the number of the clicked square210 public void SendClickedSquare( int location )211 {212 // if it is the current player's move right now213 if ( myTurn )214 {215 // send the location of the move to the server216 writer.Write( location );217 218 // it is now the other player's turn219 myTurn = false;220 }221 }222 223 // write-only property for the current square224 public Square CurrentSquare225 {226 set227 {228 currentSquare = value;229 }230 }231 232 } // end class Client
2002 Prentice Hall.All rights reserved.
Outline43
Client.cs Program Output
2002 Prentice Hall.All rights reserved.
Outline44
Client.cs Program Output
2002 Prentice Hall.All rights reserved.
Outline45
Client.cs Program Output
Server output after(1.)
Server output after (2.)
Server output after (3.)
Server output after (4.)
2002 Prentice Hall.All rights reserved.
Outline46
Square.cs
1 // Fig. 22.7: Square.cs2 // A Square on the TicTacToe board.3 4 using System.Windows.Forms;5 6 // the representation of a square in a tic-tac-toe grid7 public class Square8 {9 private Panel panel;10 private char mark;11 private int location;12 13 // constructor14 public Square( Panel newPanel, char newMark, int newLocation )15 {16 panel = newPanel;17 mark = newMark;18 location = newLocation;19 }20 21 // property SquarePanel; the panel which the square represents22 public Panel SquarePanel23 {24 get25 {26 return panel;27 }28 } // end property SquarePanel29
2002 Prentice Hall.All rights reserved.
Outline47
Square.cs
30 // property Mark; the mark of the square31 public char Mark32 {33 get34 {35 return mark;36 }37 38 set39 {40 mark = value;41 }42 } // end property Mark43 44 // property Location; the square's location on the board45 public int Location46 {47 get48 {49 return location;50 }51 } // property Location52 53 } // end class Square