1. TCP Server
The server’s job is to set up an endpoint for clients to connect to and passively wait for connections.
The typical TCP server goes through two steps:
1. Construct a TcpListener instance, specifying the local address and port, and call the Start() method.
This socket listens for incoming connections on the specified port.
2. Repeatedly:
■ Call the AcceptTcpClient() method of TcpListener to get the next incoming
client connection. Upon establishment of a new client connection, an instance of
TcpClient for the new connection is created and returned by the AcceptTcp-
Client() call.
■ Communicate with the client using the Read() and Write() methods of TcpClient’s
NetworkStream.
■ Close the new client socket connection and stream using the Close() methods of
NetworkStream and TcpClient.
TcpEchoServer.cs
using System; // For Console, Int32, ArgumentException, Environment using System.Net; // For IPAddress using System.Net.Sockets; // For TcpListener, TcpClient class TcpEchoServer { private const int BUFSIZE = 32; // Size of receive buffer static void Main(string[] args) { if (args.Length > 1) // Test for correct # of args throw new ArgumentException("Parameters: [<Port>]"); int servPort = (args.Length == 1) ? Int32.Parse(args[0]): 7; TcpListener listener = null; try { // Create a TCPListener to accept client connections listener = new TcpListener(IPAddress.Any, servPort); listener.Start(); } catch (SocketException se) { Console.WriteLine(se.ErrorCode + ": " + se.Message); Environment.Exit(se.ErrorCode); } byte[] rcvBuffer = new byte[BUFSIZE]; // Receive buffer int bytesRcvd; // Received byte count for (;;) { // Run forever, accepting and servicing connections TcpClient client = null; NetworkStream netStream = null; try { client = listener.AcceptTcpClient(); // Get client connection netStream = client.GetStream(); Console.Write("Handling client - "); // Receive until client closes connection, indicated by 0 return value int totalBytesEchoed = 0; while ((bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0) { netStream.Write(rcvBuffer, 0, bytesRcvd); totalBytesEchoed += bytesRcvd; } Console.WriteLine("echoed {0} bytes.", totalBytesEchoed); // Close the stream and socket. We are done with this client! netStream.Close(); client.Close(); } catch (Exception e) { Console.WriteLine(e.Message); netStream.Close(); } } } }
The TcpListener listens for client connection requests on the port specified in the constructor.
Be careful to use a port that is not in use by another application, or a SocketException will be thrown.
Loop forever, iteratively handling incoming connections.
Receive and repeat data until the client closes.
Close the client stream and socket.
TcpEchoClient.cs
using System; // For String, Int32, Console, ArgumentException using System.Text; // For Encoding using System.IO; // For IOException using System.Net.Sockets; // For TcpClient, NetworkStream, SocketException class TcpEchoClient { static void Main(string[] args) { if ((args.Length < 2) || (args.Length > 3)) { // Test for correct # of args throw new ArgumentException("Parameters: <Server> <Word> [<Port>]"); } String server = args[0]; // Server name or IP address // Convert input String to bytes byte[] byteBuffer = Encoding.ASCII.GetBytes(args[1]); // Use port argument if supplied, otherwise default to 7 int servPort = (args.Length == 3) ? Int32.Parse(args[2]) : 7; TcpClient client = null; NetworkStream netStream = null; try { // Create socket that is connected to server on specified port client = new TcpClient(server, servPort); Console.WriteLine("Connected to server... sending echo string"); netStream = client.GetStream(); // Send the encoded string to the server netStream.Write(byteBuffer, 0, byteBuffer.Length); Console.WriteLine("Sent {0} bytes to server...", byteBuffer.Length); int totalBytesRcvd = 0; // Total bytes received so far int bytesRcvd = 0; // Bytes received in last read // Receive the same string back from the server while (totalBytesRcvd < byteBuffer.Length) { if ((bytesRcvd = netStream.Read(byteBuffer, totalBytesRcvd, byteBuffer.Length - totalBytesRcvd)) == 0) { Console.WriteLine("Connection closed prematurely."); break; } totalBytesRcvd += bytesRcvd; } Console.WriteLine("Received {0} bytes from server: {1}", totalBytesRcvd, Encoding.ASCII.GetString(byteBuffer, 0, totalBytesRcvd)); } catch (Exception e) { Console.WriteLine(e.Message); } finally { netStream.Close(); client.Close(); } } }