The TcpClient Class



The TcpClient Class

The TcpClient class, located in the System.Net.Sockets namespace, was designed to facilitate the writing of TCP client applications by bypassing the need to use the Socket class TCP functions. This section describes the TcpClient class and presents a simple TCP client application that uses the TcpClient class.

The TcpClient Class Constructors

The TcpClient class allows you to create a TcpClient object using three constructor formats:

TcpClient() The first constructor format creates a new TcpClient object, binding a socket to the local system address and a random TCP port. After the default TcpClient object is created, it must be connected to a remote device using the Connect() method, described in the upcoming section, "The TcpClient Class Methods." Here is the format for this constructor:

TcpClient newcon = new TcpClient();
newcon.Connect("www.ispnet.net", 8000);

TcpClient(IPEndPoint localEP) The second constructor allows you to specify a specific local IP address to use, as well as a specific TCP port number. This is most often used when the device has more than one network card, and you want to specifically send packets out a particular card. Again, after the TcpClient object is created, it must be connected to a remote device using the Connect() method. Here’s the format:

IPEndPoint iep = new IPEndPoint(IPAddress,Parse("192.168.1.6"), 8000);
TcpClient newcon = new TcpClient(iep);
newcon.Connect("www.isp.net", 8000);

TcpClient(String host, int port) The third constructor format is the most frequently used. It allows you to specify the remote device within the constructor, and no Connect() method is needed. The remote device can be specified by its address and numeric TCP port value. The address can be either a string hostname, or a string IP address. The TcpClient constructor will automatically resolve the string hostname into the proper IP address. The format is as follows:

TcpClient newcon = new TcpClient("www.isp.net", 8000);

Once the TcpClient object has been created, several properties and methods are available with which to manipulate the object and transfer data back and forth with the remote device.

The TcpClient Class Methods

The TcpClient class contains a helpful collection of properties and methods to assist your efforts in writing TCP client applications. Figure shows the methods available for the TcpClient class.

Figure: TcpClient Methods

Method

Description

Close()

Closes the TCP connection

Connect()

Attempts to establish a TCP connection with a remote device

Equals()

Determines if two TcpClient objects are equal

GetHashCode()

Gets a hash code suitable for use in hash functions

GetStream()

Gets a Stream object that can be used to send and receive data

GetType()

Gets the Type of the current instance

ToString()

Converts the current instance to a String object

As mentioned earlier, the Connect() method connects the TcpClient object to a remote device. Once the device is connected, the GetStream() object assigns a NetworkStream object to send and receive data:

TcpClient newcon = new TcpClient()
newcon.Connect("www.ispnet.net", 8000);
NetworkStream ns = new NetworkStream(newcon);

After the NetworkStream object is created, you can use the Read() and Write() methods to receive and send data (this is described in Chapter 5, "Connection-Oriented Sockets").

In addition to the TcpClient class methods, there are several properties that can be used with the TcpClient object, as described in Figure. These properties allow you to set low-level Socket object options for the TcpClient object.

Figure: TcpClient Object Properties

Property

Description

LingerState

Gets or sets the socket linger time

NoDelay

Gets or sets the delay time used for sending or receiving TCP buffers that are not full

ReceiveBufferSize

Gets or sets the size of the TCP receive buffer

ReceiveTimeout

Gets or sets the receive timeout value of the socket

SendBufferSize

Gets or sets the size of the TCP send buffer

SendTimeout

Gets or sets the send timeout value of the socket

Creating a Simple Client Program

The TcpClient class was designed to make network program creation as simple as possible. You have probably already concluded from the code snippets shown so far that a basic TCP client program can be written with just a few lines of code. Listing 7.1 is a simple TCP client program that will interact with Chapter 5’s SimpleTcpSrvr program.

Listing 7.1: The TcpClientSample.cs program
Start example
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class TcpClientSample
{
  public static void Main()
  {
   byte[] data = new byte[1024];
   string input, stringData;
   TcpClient server;
   try
   {
     server = new TcpClient("127.0.0.1", 9050);
   } catch (SocketException)
   {
     Console.WriteLine("Unable to connect to server");
     return;
   }
   NetworkStream ns = server.GetStream();
   int recv = ns.Read(data, 0, data.Length);
   stringData = Encoding.ASCII.GetString(data, 0, recv);
   Console.WriteLine(stringData);
   while(true)
   {
     input = Console.ReadLine();
     if (input == "exit")
      break;
     ns.Write(Encoding.ASCII.GetBytes(input), 0, input.Length);
     ns.Flush();
     data = new byte[1024];
     recv = ns.Read(data, 0, data.Length);
     stringData = Encoding.ASCII.GetString(data, 0, recv);
     Console.WriteLine(stringData);
   }
   Console.WriteLine("Disconnecting from server...");
   ns.Close();
   server.Close();
  }
}
End example

Because the version of the TcpClient constructor used in this example automatically tries to connect to the specified remote server, it is a good idea to place it within a try-catch block in case the remote server is unavailable. As is true for the Socket method Connect() method, if the remote server is unavailable, a SocketException will be generated.

Warning 

There is one catch to placing the TcpClient constructor within a try-catch block: variables instantiated in a try-catch block are only visible within the block. To make the TcpClient object visible outside the try-catch block, you must declare the variable outside the try-catch block, as shown in Listing 7.1 with the server TcpClient object.

After the NetworkStream object is created, you use the normal Read() and Write() methods to move the data:

while(true)
{
  input = Console.ReadLine();
  if (input == "exit")
   break;
  ns.Write(Encoding.ASCII.GetBytes(input), 0, input.Length);
  ns.Flush();
  data = new byte[1024];
  recv = ns.Read(data, 0, data.Length);
  stringData = Encoding.ASCII.GetString(data, 0, recv);
  Console.WriteLine(stringData);
}

The Read() method requires three parameters:

  • The data-byte array in which to place the received data

  • The offset location in the buffer at which you want to start placing the data

  • The length of the data buffer

Like the Socket method Receive(), the object’s Read() method will read as much data as it can fit into its buffer. If the supplied buffer is too small, the leftover data stays in the stream for the next Read() method call.

The Write() method, too, requires three parameters:

  • The data-byte array to send to the stream

  • The offset location in the buffer from which you want to start sending data

  • The length of the data to send

    Note 

    It is important to remember that TCP does not preserve message boundaries. This fact also applies to the TcpClient class. By now you’ll recognize that this method should be handled the same way as the Receive() method in the TCP Socket class, creating a loop to ensure that all of the required data is read from the stream.

Testing the Program

You can test the new TcpClientSample program with the original SimpleTcpSrvr program (Listing 5.1) presented in Chapter 5. Just start SimpleTcpSrvr on the designated device, and run TcpClientSample from either a separate command-prompt window on the same machine or from a separate machine on the network. Remember to change the IP address in the program to the correct IP address for your server machine.

The TcpClientSample program should behave exactly like the NetworkStreamTcpClient program presented in Chapter 5 (Listing 5.9). You can type phrases at the console window and watch them displayed on the server and echoed back to the client.

Use the windump or analyzer commands if you want to watch the network traffic generated from your tests. Figure shows a sample Analyzer output from monitoring a test.

Click To expand
Figure: Sample Analyzer output from the TcpClientSample test

As you can see from the sample output, TcpClientSample behaves exactly the same as Chapter 5’s SimpleTcpClient program, which used Socket objects. This demonstrates that you can often use the TcpClient class in place of Socket objects, saving yourself substantial programming effort.

 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows