TCP Communication



TCP Communication

The TCP/IP protocol stack is the most popular networking stack in the world. More traffic runs over IP than anything else. IP is a lower level networking protocol designed for the Internet. As a matter of fact, IP stands for Internet Protocol. Built on top of IP are two very popular networking protocols: the connection orientated TCP (the Transmission Control Protocol) and the connectionless UDP.

When you need to communicate data between two computers, often you want not a single message, but a conversation or a dialog of messages, to occur. TCP is designed for these dialogs of messages. UDP, on the other hand, is designed for one-way messages in which the dialog (if any) happens at a higher, application level. Sending someone a letter via the postal service is a connectionless, UDP-style message. Mail is connectionless. When you call someone on the phone, you are establishing a connection with that person. You say something, they say something, you say something else, and so on. This is a connection-oriented dialog, like TCP.

TCP provides a virtual connection to another machine. It enables you to send messages in a sequence and even receive acknowledgment of delivery, which also means that you can also have re-transmission of messages—that is, reliable communication. (TCP provides reliable communication even over other transports that may be unreliable.) In the TCP specification, messages are called packets. Each packet can be up to 65,535 bytes in length, although in practice they are usually smaller. On the wire, each packet resembles Figure.

1. A TCP Packet

graphics/07fig01.gif

With Web services and SOAP, you may want to send a SOAP message reliably, or as a one-way message. HTTP is a protocol built on top of TCP, because there is one connection to handle both a request message and a response message. SOAP messages that go over HTTP travel over TCP at a lower level. Alternatively, you could also send SOAP messages over plain TCP without the HTTP wrappings. To create TCP connections with .NET, you can use either the System.Net.Sockets.Socket class or the much easier System.Net.Sockets.TcpClient and System.Net.Sockets.TcpListener classes. Let's build a simple Windows chat application that shows how TCP dialogs can be written. The final application will resemble Figure.

2. A Small Chat Application

graphics/07fig02.gif

To send data over a TCP connection, you use the TcpClient class. This class needs the other side's address and the port to which to connect. Here is the relevant code:

TcpClient tcpClient = new TcpClient(); 
tcpClient.Connect(txtServer.Text, 55);

Assuming that you establish the connection successfully, you then can read or write from the client's NetworkStream object:

NetworkStream stream = tcpClient.GetStream(); 

It's important to check this NetworkStream, to make sure that you can either read or write to it, depending on what you want to do:

if(stream.CanWrite && stream.CanRead) 

Assuming that you can write to it, you need to create an array of bytes to write to the stream. In the example you are building with this code, you will be writing ASCII text, and the System.Text.Encoding.ASCII object has a static method just for this purpose:

Byte[] buffer = Encoding.ASCII.GetBytes(txtWords.Text); 

Now, you just write out the text over the network, using the NetworkStream's Write method:

stream.Write(buffer, 0, buffer.Length); 

At this point, the other side will receive a TCP message with the contents of the txtWords' Text property.

To listen for messages that may be sent, use the TcpListener class. When you create this class, you can set the port to which it should listen. (It doesn't need the server name because it is the server.) For example:

TcpListener listener = new TcpListener( 55 ); 

Once you've created this, you need to call the Start method to have it start listening for requests, as follows. This call doesn't block.

listener.Start(); 

At this point, you can listen for any pending requests, or just wait for a blocked method call. AcceptTcpClient will block until a connection is received, and then return a TcpClient object. There is also an AcceptSocket method, which will return a Socket. For example:

TcpClient client = listener.AcceptTcpClient(); 

Now, you need to read the NetworkStream off of the TcpClient to receive messages, and write to the stream to send them. In this case, you want to receive a message from the client. The following code accomplishes this:

NetworkStream stream = client.GetStream(); 
Byte[] buffer = new Byte[1024];
int read = stream.Read( buffer, 0, 1024);
MessageBox.Show( Encoding.ASCII.GetString( buffer, 0, read ) );

A modification to this sample would be to use System.Threading.Thread to spin off the listener on its own thread. Otherwise, it would be blocked on the main thread, which would include the user interface for this application. Note that all of the messages sent in this application are plain old text, but you could easily modify it to send actual SOAP messages.