<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Martijn's C# Programming Blog &#187; sockets</title>
	<atom:link href="http://www.dijksterhuis.org/tag/sockets/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dijksterhuis.org</link>
	<description>Information, news about programming in C#</description>
	<lastBuildDate>Fri, 07 Aug 2009 21:26:47 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Building a TCP/IP server using C#</title>
		<link>http://www.dijksterhuis.org/building-a-tcpip-server-using-c/</link>
		<comments>http://www.dijksterhuis.org/building-a-tcpip-server-using-c/#comments</comments>
		<pubDate>Mon, 17 Nov 2008 09:21:17 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Beginner]]></category>
		<category><![CDATA[Learn C#]]></category>
		<category><![CDATA[listener]]></category>
		<category><![CDATA[sockets]]></category>
		<category><![CDATA[tcp]]></category>

		<guid isPermaLink="false">http://www.dijksterhuis.org/?p=150</guid>
		<description><![CDATA[
Dozens of protocols have come and gone (does anyone even remember IPX/SPX?) but both TCP &#038; UDP over IP survive. C# offers a good deal of libraries for handling connections both on the server and client side. Here we look at how to build a simple server in increasing steps of complexity.

Before we get started
This [...]<p>This is a post from <a href="http://www.dijksterhuis.org">Martijn's C# Coding Blog</a>. </p>
]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.dijksterhuis.org/wp-content/uploads/2008/11/tcp.jpg" alt="" title="Building a TCP/IP server using C#" width="500" height="258" class="alignnone size-full wp-image-162" /><br />
<em>Dozens of protocols have come and gone (does anyone even remember IPX/SPX?) but both TCP &#038; UDP over IP survive. C# offers a good deal of libraries for handling connections both on the server and client side. Here we look at how to build a simple server in increasing steps of complexity.</em></p>
<p><span id="more-150"></span></p>
<h3>Before we get started</h3>
<p>This article will show how to build a little TCP server that passes a simple message to each connecting client. The first two examples use synchronous IO, the final one uses asynchronous connects. </p>
<p>Each of the following programs will try to do the following:</p>
<ol>
<li>Setup the TCP stack
<li>Listen for an incoming TCP connection (localhost , port 2200)
<li>Accept the connection
<li>Display the IP adres of the caller, and the port from the remote system
<li>Send the message &#8220;I am a little busy, come back later&#8221;
<li>Close the connection
<li>Goto 2</ol>
<p><strong>So what local address is it anyway?</strong></p>
<p>Each computer with TCP networking has an assigned network address which is in the form x.x.x.x (10.0.0.6) This is of course IPv4, we will leave IPv6 for another day. If the computer has more than one network card then there will be more than one address.</p>
<p>On top of that there are two more addresses of significance:</p>
<ul>
<li>&#8220;0.0.0.0&#8243;  &#8211; If we set this as the source address, your program will listen on all available network cards in the computer
<li>&#8220;127.0.0.1&#8243; &#8211; This is the local loopback. Any program that binds itself to this is only available for programs on the same computer
</ul>
<p>To make it possible for multiple programs to use the network interface, each can listen to a 16 bit &#8220;port&#8221; (0 &#8211; 65536, with 0-1024 typically reserved for system services). For our little server we randomly picked a port: 2200.</p>
<p>It is perfectly possible for a program to only bind itself to only one network card (eg. a web server being available only on the extenal interface) or to all at the same time. We will bind to 127.0.0.1 in the examples below. As a result the &#8220;server&#8221; is only available to programs on the same computer.</p>
<h3>Version 1 &#8212; TcpListener is slighlty easier to code</h3>
<p>To avoid having to delve too deep into the TCP stack , the <em>System.Net.Sockets.TcpClient</em> and <em>System.Net.Sockets.TcpListener</em> classes make available a slightly &#8220;easier&#8221; interface to sending and receiving data over a network. In addition it is possible to send and receive data through a <em>NetworkStream</em> object. These classes all add some overhead, but since our example is simple we won&#8217;t notice:</p>
<ul>
<li>TcpListener allows us to listen for an incoming connection
<li>TcpClient handles the actual connection
<li>NetworkStream sends and receives the actual data
</ul>
<pre class="brush: c#">
namespace SimpleServer
{
    class Program
    {
        public static void Main()
        {
            // Data is send in bytes -- so we need to convert a C# string to a Byte[]
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            Byte[] message = encoding.GetBytes(&quot;I am a little busy, come back later!&quot;);

            try
            {
                // Setup a listener at the local IP adres, port 2200
                IPAddress localAddress = IPAddress.Parse(&quot;127.0.0.1&quot;);
                TcpListener listener = new TcpListener(localAddress,2200);

                // Start listening, only allow 1 connection to queue at the same time
                listener.Start(1);

                // Start listening for connections.
                while (true)
                {
                    Console.WriteLine(&quot;Server is waiting on socket {0}&quot;, listener.LocalEndpoint);

                    // The program is suspended while waiting for an incoming connection.
                    // This is a synchronous TCP application
                    TcpClient client = listener.AcceptTcpClient();

                    // Obtain a stream object for reading and writing
                    NetworkStream io = client.GetStream();

                    // An incoming connection needs to be processed.
                    Console.WriteLine(&quot;Received Connection from {0}&quot;, client.Client.RemoteEndPoint );

                    Console.WriteLine(&quot;Sending message..&quot;);
                    io.Write(message, 0, message.Length);

                    // End of the incomming connection
                    Console.WriteLine(&quot;Ending the connection&quot;);
                    client.Close();
                }

            }
            catch (Exception e)
            {
                Console.WriteLine(&quot;Caught Exception: {0}&quot;, e.ToString());
            }
        }
    }
}
</pre>
<p>Run the program in the debugger; and when tracing it step by step it will stop at the following line:</p>
<pre class="brush: c#">
TcpClient client = listener.AcceptTcpClient();
</pre>
<p>We are doing &#8220;synchronous&#8221; communication &#8212; we need to wait for a connection to arrive before the program is allowed to continue.</p>
<p>Fire up telnet (from the command prompt) and connect to our little server. Continue to step through the code as we connect. The following will do the trick:</p>
<pre class="brush: c#">
telnet localhost 2200
</pre>
<pre class="brush: c#">
Server is waiting on socket 127.0.0.1:2200
Received Connection from 127.0.0.1:4883
Sending message..
Ending the connection
Server is waiting on socket 127.0.0.1:2200
</pre>
<p>The Telnet window will show the message passed on by the server:</p>
<pre class="brush: php">
I am a little busy, come back later!
Connection to host lost.
</pre>
<p>And the program is back at the beginning, rinse and repeat.</p>
<p><!--more--></p>
<h3>Version 2 &#8212; Using sockets for our communication</h3>
<p>As there is some overhead associated with TcpListener and TcpClient, we need to modify our program to gain that ounce of extra performance. In the following example we drop both these classes and instead directly use the <em>System.Net.Sockets.Socket</em> class.</p>
<p>The actual difference in code is mostly in the setup of the connection:</p>
<pre class="brush: c#">
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
</pre>
<p>I might have made fun of other network stacks earlier, but that doesn&#8217;t mean we can&#8217;t connect to them and if your computer has the support for them its possible to connect to many other kinds of networks.</p>
<pre class="brush: c#">
AddressFamily.InternetWork provides access to IPv4 networks
AddressFamily.InternetWorkV6 provides access to IPv6 networks
</pre>
<p>And then of course there is AppleTalk, ATM, Banyan, Chaos, DataKit, DecNet, Iso, Osi,&#8230;.</p>
<p>SocketType.Stream provides reliable two-way communication, For connectionless UDP) you would use SocketType.Dgram. And if you would like get really low access SocketType.Raw (it returns the IP packet including all the headers) might do the trick.</p>
<p>ProtocolType provides the higher level protocol, in our case we stick with Tcp. Other common options would be Udp or Icmp.</p>
<pre class="brush: c#">
// This will bind us to the first IP address found on this computer
IPAddress localAddress = IPAddress.Parse(&quot;127.0.0.1&quot;);

// Define the address we want to claim: the first IP address found earlier, at port 2200
IPEndPoint ipEndpoint = new IPEndPoint(localAddress, 2200);

// Bind the socket to the end point
listenSocket.Bind(ipEndpoint);

// Start listening, only allow 1 connection to queue at the same time
listenSocket.Listen(1);
</pre>
<p>Similar to TCPListener we need to bind and listen to port 127.0.0.1:2200, it just requires a few more steps.</p>
<pre class="brush: c#">
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace SimpleServerUsingSockets
{
    class Program
    {
        public static void Main()
        {
            // Q&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;A: How to convert a C# string to a byte[] array ?
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();

            try
            {
                // This will bind us to the first IP address found on this computer
                IPAddress localAddress = IPAddress.Parse(&quot;127.0.0.1&quot;);

                // Define the kind of socket we want: Internet, Stream, TCP
                Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                // Define the address we want to claim: the first IP address found earlier, at port 2200
                IPEndPoint ipEndpoint = new IPEndPoint(localAddress, 2200);

                // Bind the socket to the end point
                listenSocket.Bind(ipEndpoint);

                // Start listening, only allow 1 connection to queue at the same time
                listenSocket.Listen(1);

                // Start listening for connections -- the program loops forever
                while (true)
                {
                    Console.WriteLine(&quot;Server is waiting on socket {0}&quot;, ipEndpoint);

                    // The program is suspended while waiting for an incoming connection.
                    // This is a synchronous TCP application
                    Socket handler = listenSocket.Accept();

                    // An incoming connection needs to be processed.
                    Console.WriteLine(&quot;Received Connection from {0}&quot;, handler.RemoteEndPoint);

                    Console.WriteLine(&quot;Sending message..&quot;);
                    handler.Send(encoding.GetBytes(&quot;I am a little busy, come back later!&quot;));

                    // End of the incomming connection
                    Console.WriteLine(&quot;Ending the connection&quot;);
                    handler.Close();
                }

            }
            catch (Exception e)
            {
                Console.WriteLine(&quot;Caught Exception: {0}&quot;, e.ToString());
            }
        }
    }
}
</pre>
<h3>Version 3 &#8212; We don&#8217;t want to wait any longer</h3>
<p>The above two examples used synchronous IO. We need to wait for the remote system to make a connection before the program can continue. Of course, in real life we would like to our little server to do much more. For this we need asynchronous IO. Our program will be notified by the operating system every time it needs to do something but it is otherwise free to continue.</p>
<p>The hard work is done by &#8220;BeginAccept&#8221; and &#8220;EndAccept&#8221;. In &#8220;BeginAccept&#8221; we specify a callback function which is called as soon as a connection is made. In the callback function itself we need to use &#8220;EndAccept&#8221; to retrieve the socket with which to communicate to our client. </p>
<pre class="brush: c#">
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace SimpleServer
{
    class Program
    {
        public static void ReceiveCallback(IAsyncResult AsyncCall)
        {
            // Data is send in bytes -- so we need to convert a C# string to a Byte[]
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            Byte[] message = encoding.GetBytes(&quot;I am a little busy, come back later!&quot;);

            // The original listening socket is returned in the AsyncCall, we need to call &quot;EndAccept&quot; to
            // receive the client socket which we can use to send and receive data.
            Socket listener = (Socket)AsyncCall.AsyncState;
            Socket client = listener.EndAccept(AsyncCall);

            Console.WriteLine(&quot;Received Connection from {0}&quot;, client.RemoteEndPoint);
            client.Send(message);

            // End of the incoming connection
            Console.WriteLine(&quot;Ending the connection&quot;);
            client.Close();

            // At the end of the connection, we need to tell the OS that we can receive another call
            listener.BeginAccept(new AsyncCallback(ReceiveCallback), listener);
        }

        public static void Main()
        {
            try
            {

                IPAddress localAddress = IPAddress.Parse(&quot;127.0.0.1&quot;);

                // Define the kind of socket we want: Internet, Stream, TCP
                Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                // Define the address we want to claim: the first IP address found earlier, at port 2200
                IPEndPoint ipEndpoint = new IPEndPoint(localAddress, 2200);

                // Bind the socket to the end point
                listenSocket.Bind(ipEndpoint);

                // Start listening, only allow 1 connection to queue at the same time
                listenSocket.Listen(1);
                listenSocket.BeginAccept(new AsyncCallback(ReceiveCallback), listenSocket);
                Console.WriteLine(&quot;Server is waiting on socket {0}&quot;, listenSocket.LocalEndPoint);

                // Start being important while the world rotates
                while (true)
                {
                    // Write a message and sleep for 2 seconds
                    Console.WriteLine(&quot;Busy Waiting....&quot;);
                    Thread.Sleep(2000);
                }

            }
            catch (Exception e)
            {
                Console.WriteLine(&quot;Caught Exception: {0}&quot;, e.ToString());
            }
        }
    }
}
</pre>
<p>Now again, using the earlier telnet code example try connecting to this thread a few times. </p>
<p>This is not the only way to free up your programs main thread for more important work. Another approach could have been to stick with a (logically) easier synchronous server but instead create a new thread to run it in.</p>
<p><small>Image credit: <a rel="nofollow" href="http://www.flickr.com/photos/nnova/">nicolasnova</a></small></p>
<p>This is a post from <a href="http://www.dijksterhuis.org">Martijn's C# Coding Blog</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.dijksterhuis.org/building-a-tcpip-server-using-c/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
