Skip Navigation LinksHome / Articles / View Article

Sockets and their implementation in SL2 Beta 1 including a chat-like example

+ Add to SilverlightShow Favorites
0 comments   /   posted by Denislav Savkov on May 22, 2008
(0 votes)
Categories: Controls , Tutorials , Samples , Issues

Introduction

Sockets are well-known to many programmers today but this article is for the rest who aren’t familiar with them yet. Here we will also review an example of using sockets in Silverlight and their beta peculiarities. You can download the example and read the instructions for it at the end of the article.

Download source code

Overview of sockets in general

To begin with, some preliminary information will be helpful. Sockets are used for communication among applications over a network. Network architecture can be generalized as consisting of four layers:
1. Application
2. Transport
3. Network
4. Link and Physical
Each layer communicates only to the layer above and to the layer below it.
-The Application layer provides services for communication among applications; such are FTP, HTTP, DNS and DHCP.
- The transport layer is responsible for delivering data to the appropriate application process on the host computers. Most common protocols are TCP and UDP (Transmission Controlled Protocol and Universal Datagram Protocol).
-The network layer is responsible for routing i.e. dealing with addresses and source to a destination delivery. A well-known example is the IP (Internet Protocol).
-The link and physical layers are responsible for the hardware realization (Ethernet, Wi-Fi).
Sockets are used in IP-based networks and therefore they are also called internet sockets. They are used by the OS as an interface between an application, the transport and network layers (for example TCP/IP).  Consequently, they hold information about the network protocol and the transport protocol that are used, and other options such as the socket type. Notice that an application chooses which network to connect to but communicates only through the transport layer.
Concept
Endpoint – represents one end of a transport layer connection
Port – it is the point of contact between application and connection

 

Socket Types

There are several socket types. We will examine only two of them. The first is the stream socket. It creates a two-way connection between two endpoints which is called a stream. Data sent through such socket is received in the order that it has been sent. Such sockets use TCP. Many applications like chat clients and browsers use them. The data integrity is guaranteed. This is not the case with the datagram sockets. Datagram sockets don’t use connection and that’s why they are called “connectionless”. They don’t guarantee the successful delivery of all packets or that they will be received in the order they have been sent. Thus it avoids checking whether every packet is delivered. This results in a faster, more efficient delivery. Datagram sockets use UDP. They are used for applications which require speed and errors such as online/network games, media streaming and Domain Name Service (DNS) are admissible.
 

Server/Client

Sockets are based on the Server/Client mode. How does it work? In WPF the class Socket implements both a server and a client.
Server performs at least the following steps to complete a session:
         Creates a socket.
         Binds the socket to a port.
         Opens the port for listening.
         Accepts the incoming connection.
         Communicates data.
         Closes the opened socket.
The client on its behalf performs the following:
         Creates a socket.
         Connects to the server.
         Communicates data.
         Closes the connection.
 

Sockets in Silverlight 2 Beta 1

Silverlight 2 Beta 1 implements only a part of the concept. The first big restriction is that only the client side of Socket is implemented in the beta. This means you can only connect to a server but you cannot host one. For our Silverlight example we exploit the Asynchronous sockets server example directly from the MSDN library. You should be able to connect to any other listening socket (here comes the second restriction) on the host from which the Silverlight application has been downloaded. This means the beta cannot connect to another computer. Also the only available ports for connection from Silverlight 2 Beta 1 are in the range 4502-4532. These restrictions give very small functionality to the Beta 1 applications but for the next Beta 2 release Microsoft promise full functionality. Now if you try to connect to a different host or to a port out of the indicated range you will get this error: “establishing connection, An attempt was made to access a socket in a way forbidden by its access permissions”. In our example we start the listening socket at port 4509 on the localhost (the IP for the localhost is 127.0.0.1). The Silverlight host project on the other hand starts at port 4501 on the localhost.
For more information on Silverlight sockets we recommend reading the MSDN working with Sockets article.

Our example

First let me point a little oddity. To get access to the Socket class in System.Net namespace we had to add System.Net as a reference. This is valid if we want to work with sockets inside a Silverlight user control.
The Socket class in SL2 B1 implements asynchronous operations. This design pattern allows starting operation in a separate thread and the result is that we have a separation between the high and the low-priority operations like user interface and background operations. Here I use an example class (SocketClient) posted on Michael's Blog with just a few changes.
First initialize the endpoint and the socket type.
String safeHost = Application.Current.Host.Source.DnsSafeHost;
int port = 4509;
socketClient = new SocketClient( safeHost, port );
 
internal SocketClient( string host, int port )
{
      endPoint = new DnsEndPoint( host, port );
socket = new Socket( AddressFamily.InterNetwork,
                 SocketType.Stream, ProtocolType.Tcp );           
}
An asynchronous operation has a callback function which is called when the operation is completed. The SocketAsyncEventArgs object that contains information about the operation is hooked to OnConnect.
internal void Connect()
{
    SocketAsyncEventArgs args = new SocketAsyncEventArgs();
 
    args.UserToken = socket;
    args.RemoteEndPoint = endPoint;
    args.Completed += new EventHandler<SocketAsyncEventArgs>( OnConnect );
 
autoEvent.WaitOne() puts the thread to sleep until autoEvent.Set() is called. This way we make sure that ConnectAsync() has completed before proceeding.
 
 
    socket.ConnectAsync( args );
    autoEvent.WaitOne();
 
If the connection is successful we send Connected message outside the class.
 
    if( args.SocketError != SocketError.Success )
        throw new SocketException( ( int )args.SocketError );
    if( IsConnected )
        this.Connected( this, new EventArgs() );
}

 

This leads to an update in the interface: 

 . . .
      socketClient.Connected += new EventHandler( socketClient_Connected );
      socketClient.Connect();
    }
}
 
void socketClient_Connected( object sender, EventArgs e )
{
    Say( "Connected" );
    ConnectButton.Content = "Disconnect";
}
 
Now that we have connected to the server we start sending messages. We fill the necessary fields of a SocketAsyncEventArgs object and send asynchronously.
internal String SendReceive( string message )
{
    if( isConnected )
    {
        Byte[] bytes = Encoding.UTF8.GetBytes( message );
 
        SocketAsyncEventArgs args = new SocketAsyncEventArgs();
        args.SetBuffer( bytes, 0, bytes.Length );
        args.UserToken = socket;
        args.RemoteEndPoint = endPoint;
 
        socket.SendAsync( args );
. . .
 
The UI (and the logic for the UI for this example) shows how convenient and quick it is to work with Silverlight especially regarding UI. The example represents a one-sided chat that can only send messages. To present visually the messages I use a StackPanel in which I put a TextBlock containing every new message.
public void Say( string youSaid )
{
    if( TextStack.Children.Count > 10 )
        TextStack.Children.RemoveAt( 1 );
    TextBlock newText = new TextBlock();
    newText.Text = youSaid;
    TextStack.Children.Add( newText );
}

  

Instructions for the example

This example contains two solutions. They both should be run on the same machine. They don’t operate over a network.
The one is a console application which acts as a server. To use it you only need to start it. If you want to change the port you can do that in the source code.
The other solution contains a Silverlight web project which hosts the SL client application. If you want to change the port you can do that after the application starts using the user interface.
The following procedure demonstrates how this example works:
1.    Build and start ConsoleAsynchronousSocketsServer.
2.    Build and start SilverlightAsynchronousSocketsClient.
3.    From the Silverlight project page connect to the console application.
4.    Start writing and sending messages.
5.    Disconnect.
*         You may repeat steps 3-5.
 

References

Wikipedia on sockets
MSDN Library Working with Sockets Silverlight 2
Michael  Schwarz’s blog and his SocketClient class:
Share


Comments

Comments RSS RSS
No comments

Add Comment

 
 

   
  
  
   
Please add 2 and 5 and type the answer here:

Join the free SilverlightShow webcast 'Running Silverlight Outside the Browser and with Elevated Trust'. Sept 7th, 8 am - 9 am PDT.
In this live session Chris Anderson will cover configuring and debugging OOB mode, toast notifications, elevated trust, direct file access and much more.
Learn more | Register | See more webinars (hide this)