ASClient.rar
CSharpTcpServer.rar

I will be writing some articles on Network Programming using various languages to create both the server and the clients in different parts.  In this part I will be creating a basic C# TCP Server to accept incoming connections and simply read the data which is sent to it.  I will be sending the information to the server using AS3.

I hope to do these different parts using models programmed in C#, Java and C++, although I ma not sure when the C++ versions will be complete as I am still trawling through self learning with it.  Either way, this is interesting stuff.

Resources

Before I begin I will mention some resources you can go get which will enable you to follow and run the examples yourself.

Assumptions

You have a medium to advanced understanding of C#, as this example will be demonstrating communication over TCP using Flash as the client and C# as the server.  I will be using Asynchronous programming in the C# application.  You should also have an understanding of a similar level in Action Script 3.0 .

Goals

  1. To establish a connection over TCP using Sockets from Flash to C#.
  2. To pass textual data from Flash to C# over TCP using Sockets.
  3. To pass a stream of data of varying size from the Flash Client to the Simple C# TCP Server
  4. To accept textual data sent from C# to Flash over TCP using Sockets.
  5. To serialize and post objects over TCP using XML as the vehicle and TCP as the transport going from Flash to C# and visa-versa.

The Socket class which I have using inside the action script is simply a derivative of the Socket class itself.  This is for future posts where it will be expanded to include further functionality.

BasicSocket.as
package  
{
	
	/**
	 * ...
	 * @author Andrew Rea
	 */
 import flash.events.*;
 import flash.net.Socket;
 import flash.utils.*;
 
	 public class BasicSocket extends Socket {
		 public function BasicSocket(host:String = null, port:uint = 8200){
		   super(host, port);
		  }
	}
}

Establishing a Connection over TCP using Sockets from Flash to C# and Java

Click here for the MSDN Asynchronous Programming Overview

The first thing that must be done is to establish that a connection can be made and accepted going from Flash to C# and Java.  Once this is confirmed we can move onto, using that connection to send and ultimately receive data and thus create a client server process.

Create the C# Basic TCP Server
  1. Create a new project
  2. Select windows and then a console application
  3. Give it a descriptive name like CSharpTcpServer…
  4. Add a new class to your solution and call it Server.

On the C# side we now need to create a Socket which will bind to a specific port and wait for incoming connections.  We will then trace out into the console window when we receive the connection.  The connection will be initialized from the Flash client.

A Simple Server implementation in C# using Sockets.

The Simple Server will have two public methods of Start() and Stop().  It will then contain a protected asynchronous method of OnClientConnected(IAsyncResult result) which will be called once a connection is accepted on the Server Socket.  Inside the OnClientConnected(IAsyncResult result) the final line of code will instruct the server to start listening again so that we can accept multiple clients.  If we were not using Asynchronous methods in C'# we would have to implement a while loop, and upoon receiving a connection request, instantiate a new Thread for the client.  Asynchronous methods deal with all the work under the hood and allow for an extremely efficient work flow.

I am using the screen toaster for the example previews in this site, below you can see an example of the server using two telnet clients.  You can set up multiple clients to test this out.  If you have not used telnet before visit http://technet.microsoft.com/en-us/library/c.aspx for sample commands you can use.  For this example we are simply opening a connection to an IP and port.

Server.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace CSharpTcpServer
{
    /// <summary>
    /// A simple C# TCP Server
    /// </summary>
    public class Server
    {
        private string host;
        private int port;
        private Socket server;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="port">The port for the server to listen for connections on</param>
        public Server(int port)
        {
            //Set the port
            this.port = port;
            //Instantiate the socket for the server and we want to use Streams and TCP
            this.server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        /// <summary>
        /// Method to start the server and wait for the intial client
        /// </summary>
        public void Start()
        {
            //Makesure we can accept a connectoin from any IP but only on port 888
            this.server.Bind(new IPEndPoint(IPAddress.Any, this.port));
            //Allow a maximum backlog of 10 connections
            this.server.Listen(10);
            //Instruct the server to accept the next client connection
            this.server.BeginAccept(OnClientConneced, this.server);

            Console.WriteLine("Server started and waiting for clients...");
        }

        /// <summary>
        /// This will shut down the server and stop any tranmission from and to the server
        /// </summary>
        public void Stop()
        {
            //Makesure the server is connected before attempting to shut it down
            if (this.server.Connected)
            {
                Console.WriteLine("Server Shutting Down...");
                this.server.Shutdown(SocketShutdown.Both);
            }
        }

        /// <summary>
        /// This will be called when a client connected to the server
        /// </summary>
        /// <param name="result">The asyncronous result containing the server socket</param>
        protected void OnClientConneced(IAsyncResult result)
        {
            //Makesure the server is connected before accepting a new client
            if (!this.server.Connected)
            {
                //Cast the state of the Async Result as the Server Socket
                Socket serverSocket = (Socket)result.AsyncState;

                //Ending the Accept method will result in the Socket of the client
                Socket clientSocket = serverSocket.EndAccept(result);

                Console.WriteLine("Client Connected");

                //Now we have the client inform the server to continue listening for further clients
                this.server.BeginAccept(OnClientConneced, this.server);
            }
        }
    }
}
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSharpTcpServer
{
    class Program
    {
        private static Server server;

        static void Main(string[] args)
        {
            //Instantiate the server and use port 8888
            server = new Server(8888);

            //Start the server
            server.Start();

            //Subscribe to the console cancel key press event so we can shut down the server
            Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);

            //Block the application until it ends.
            Console.ReadLine();
        }

        static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            server.Stop();
        }
    }
}

So from the above code, if all has gone well with your application and as the quick video shows, you can debug your server and then test it out using the Telnet client.  The next part is considerably shorter in code, is in Action Script 3.0 and also acts as the client instead of the telnet client.  The following when run will simply attempt to connect to the Simple C# TCP Server, the result of which will be seen inside the console window showing that it has successfully accepted the client connection  from the flash client.

Main.as

package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.ByteArray;
	
	/**
	 * ...
	 * @author Andrew Rea
	 */
	public class Main extends Sprite 
	{
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);

			var a:BasicSocket = new BasicSocket();
			a.connect("127.0.0.1", 8888);		
		}
		
	}
}

Pass textual data from Flash to C# over TCP using Sockets.

The next step is being able to send data from the Flash client to the C# TCP Server.  All we want to send at this stage is simple text which is by default ASCII encoded.  We need to create a function which will handle the event of data being received from the client, for this we will create OnClientReceiveData(IAsyncResult).  We will initialise the function call before we instruct the server to go and wait for another client connection.  This time for the state object we need two things, which are the client socket and also the data container which we can read from the client has sent.  I have simply created an object array for this, but for the next instances we will create a dedicated object which we can an type/size of data.  Below is the revised Simple C# TCP Server and also the amended Action Script which sends the data.

Server.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace CSharpTcpServer
{
    /// <summary>
    /// A simple C# TCP Server
    /// </summary>
    public class Server
    {
        private string host;
        private int port;
        private Socket server;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="port">The port for the server to listen for connections on</param>
        public Server(int port)
        {
            //Set the port
            this.port = port;
            //Instantiate the socket for the server and we want to use Streams and TCP
            this.server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        /// <summary>
        /// Method to start the server and wait for the intial client
        /// </summary>
        public void Start()
        {
            //Makesure we can accept a connectoin from any IP but only on port 888
            this.server.Bind(new IPEndPoint(IPAddress.Any, this.port));
            //Allow a maximum backlog of 10 connections
            this.server.Listen(10);
            //Instruct the server to accept the next client connection
            this.server.BeginAccept(OnClientConneced, this.server);

            Console.WriteLine("Server started and waiting for clients...");
        }

        /// <summary>
        /// This will shut down the server and stop any tranmission from and to the server
        /// </summary>
        public void Stop()
        {
            //Makesure the server is connected before attempting to shut it down
            if (this.server.Connected)
            {
                Console.WriteLine("Server Shutting Down...");
                this.server.Shutdown(SocketShutdown.Both);
            }
        }

        /// <summary>
        /// This will be called when a client connected to the server
        /// </summary>
        /// <param name="result">The asyncronous result containing the server socket</param>
        protected void OnClientConneced(IAsyncResult result)
        {
            //Makesure the server is connected before accepting a new client
            if (!this.server.Connected)
            {
                //Cast the state of the Async Result as the Server Socket
                Socket serverSocket = (Socket)result.AsyncState;

                //Ending the Accept method will result in the Socket of the client
                Socket clientSocket = serverSocket.EndAccept(result);

                Console.WriteLine("Client Connected");

                byte[] data = new byte[1024];

                object[] dataToSend = new object[] { data, clientSocket };

                clientSocket.BeginReceive(data, 0, 1024, SocketFlags.None, OnClientRecieveData, dataToSend);
                    
                //Now we have the client inform the server to continue listening for further clients
                this.server.BeginAccept(OnClientConneced, this.server);
            }
        }

        /// <summary>
        /// When data is received from the client, it is output to the console window.
        /// Currently this function will only read from the input stream once.
        /// </summary>
        /// <param name="result">The asyncronous result containing the server socket and the incoming data</param>
        protected void OnClientRecieveData(IAsyncResult result)
        {
            object[] data = (object[])result.AsyncState;

            byte[] dataSent = (byte[])data[0];

            Socket clientSocket = (Socket)data[1];

            int dataLength = clientSocket.EndReceive(result);

            Console.WriteLine(Encoding.ASCII.GetString(dataSent, 0, dataLength));
        }
    }
}
Main.as
package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.ByteArray;
	import slideshow.event.PageChangeEvent;
	
	/**
	 * ...
	 * @author DefaultUser (Tools -> Custom Arguments...)
	 */
	public class Main extends Sprite 
	{
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);

			var a:BasicSocket = new BasicSocket();
			a.connect("127.0.0.1", 8888);
			var messageToSend:String = "Hello World";
	
			var dataToSend:ByteArray = new ByteArray();
			dataToSend.writeUTFBytes(messageToSend);
			
			a.writeUTFBytes(messageToSend);
			
		}
		
	}
}

Now we have established a connection and also sent data from Flash to the C# Server we now want to enable a constant flow of data from the Flash Client to the Simple C# TCP Server.  At present, the server would only accept a maximum of 1024 bytes of data due to the buffer size and the the function not recurring.  So now, we will change the function to check if it needs to again listen for a next chunk to the message and also introduce a class which will make it easy for us to collect the data sent from the client / s.

Pass a stream of data of varying size from the Flash Client to the Simple C# TCP Server

The flow which needs to happen is that the client sends what ever data it needs to sends. It is the server’s job to accept this data,  in the necessary sized chunks decided by the size of the buffer.  At present and for this example we will be using a 1024 byte buffer, which means if we receive data of a greater size, the server will read 1024 bytes, and then request more of the clients data.  Until the length of the data received is less than the buffer length, it will continue to loop and ask the client for more data.  It should be noted here that upon accepting the data from the client, valid handling in case the client disconnects should be present.

Before I paste the amended code of the server I will first introduce the StateObject, which I first saw on the MSDN site.  The role of this object is to persist data over multiple receive calls so that when you have collected all the data being sent you can then either cast/ read or perform the actions you need, because assuming the client or the server has not disconnected it is at this point where you have the entire data for the request.

StateObject.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net.Sockets;

namespace CSharpTcpServer
{
    /// <summary>
    /// A state object for persisting data over multiple data communications
    /// </summary>
    public class StateObject : IDisposable
    {
        //The max size of the chunks it can read at any one time
        public const int BUFFER_SIZE = 1024;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="clientSocket">The client which is connected</param>
        /// <param name="serverSocket">The server socket itself which is serving the requests of the clients</param>
        public StateObject(Socket clientSocket, Socket serverSocket)
        {
            this.clientSocket = clientSocket;
            this.serverSocket = serverSocket;
            //Instantiate the stream which will collate the data sent
            this.stream = new MemoryStream();
            //Instantiate the data array
            this.data = new byte[BUFFER_SIZE];
        }

        private MemoryStream stream;

        public MemoryStream Stream
        {
            get
            {
                return this.stream;
            }
        }

        private Socket clientSocket;

        public Socket ClientSocket
        {
            get
            {
                return this.clientSocket;
            }
        }

        private Socket serverSocket;

        public Socket ServerSocket
        {
            get
            {
                return this.serverSocket;
            }
        }

        private byte[] data;

        public byte[] Data
        {
            get
            {
                return this.data;
            }
            set
            {
                this.data = value;
            }
        }

        #region IDisposable Members

        /// <summary>
        /// Clean up
        /// </summary>
        public void Dispose()
        {
            this.stream.Close();
            this.stream = null;
        }

        #endregion
    }
}

Now we have the state object, we need to incorporate this into the Simple TCP Server.  Every time we receieve data we need to check to see if the amount of data received is less than the buffer, if it is then we need to repeat a receive async event until we have received the entire payload.  The following is the revised Server.cs class now with the ability to accept any length of data.

Server.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace CSharpTcpServer
{
    /// <summary>
    /// A simple C# TCP Server
    /// </summary>
    public class Server
    {
        private string host;
        private int port;
        private Socket server;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="port">The port for the server to listen for connections on</param>
        public Server(int port)
        {
            //Set the port
            this.port = port;
            //Instantiate the socket for the server and we want to use Streams and TCP
            this.server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        /// <summary>
        /// Method to start the server and wait for the intial client
        /// </summary>
        public void Start()
        {
            //Makesure we can accept a connectoin from any IP but only on port 888
            this.server.Bind(new IPEndPoint(IPAddress.Any, this.port));
            //Allow a maximum backlog of 10 connections
            this.server.Listen(10);
            //Instruct the server to accept the next client connection
            this.server.BeginAccept(OnClientConneced, this.server);

            Console.WriteLine("Server started and waiting for clients...");
        }

        /// <summary>
        /// This will shut down the server and stop any tranmission from and to the server
        /// </summary>
        public void Stop()
        {
            //Makesure the server is connected before attempting to shut it down
            if (this.server.Connected)
            {
                Console.WriteLine("Server Shutting Down...");
                this.server.Shutdown(SocketShutdown.Both);
            }
        }

        /// <summary>
        /// This will be called when a client connected to the server
        /// </summary>
        /// <param name="result">The asyncronous result containing the server socket</param>
        protected void OnClientConneced(IAsyncResult result)
        {
            //Makesure the server is connected before accepting a new client
            if (!this.server.Connected)
            {
                //Cast the state of the Async Result as the Server Socket
                Socket serverSocket = (Socket)result.AsyncState;

                //Ending the Accept method will result in the Socket of the client
                Socket clientSocket = serverSocket.EndAccept(result);

                Console.WriteLine("Client Connected");

                StateObject stateObj = new StateObject(clientSocket, serverSocket);

                clientSocket.BeginReceive(stateObj.Data, 0, StateObject.BUFFER_SIZE,
                    SocketFlags.None, OnClientRecieveData, stateObj);

                //Now we have the client inform the server to continue listening for further clients
                this.server.BeginAccept(OnClientConneced, this.server);
            }
        }

        /// <summary>
        /// When data is received from the client, it is output to the console window.
        /// Currently this function will only read from the input stream once.
        /// </summary>
        /// <param name="result">The asyncronous result containing the server socket and the incoming data</param>
        protected void OnClientRecieveData(IAsyncResult result)
        {
            //Cast the state back to a state object
            StateObject data = (StateObject)result.AsyncState;

            //If the client is not connected then simply return as this session has ended
            if (!data.ClientSocket.Connected)
                return;

            //Ending the async receive method will return the length of bytes in the current chunk
            int dataLength = data.ClientSocket.EndReceive(result);

            //If it is zero then we display a message of client disconnected
            //This is not complete but for the purposes of this stage of the demo this is how it is
            if (dataLength == 0)
            {
                Console.WriteLine("Client Disconnected");
            }
            else if (dataLength < StateObject.BUFFER_SIZE)
            {
                //The chunk is less than the size of the buffer which means there are no further chunks
                //inside this transmission

                //Write the data into the stream of the state object to persist it
                data.Stream.Write(data.Data, 0, dataLength);

                //Rewind the stream back the start
                data.Stream.Position = 0;

                //We are assuming that the data being sent is plain text so we can output this to the console
                //window
                Console.WriteLine(Encoding.Default.GetString(data.Stream.ToArray()));

                //Dispose of the data
                data.Dispose();

                //Instantiate a new state object for further transmissions
                data = new StateObject(data.ClientSocket, data.ServerSocket);

                //Instruct the server to wait for more data from the client
                data.ClientSocket.BeginReceive(data.Data, 0, StateObject.BUFFER_SIZE,
                    SocketFlags.None, OnClientRecieveData, data);
            }
            else
            {
                //Write the data to the state object
                data.Stream.Write(data.Data, 0, dataLength);

                //Instruct the server to wait for more data from the client
                data.ClientSocket.BeginReceive(data.Data, 0, StateObject.BUFFER_SIZE,
                    SocketFlags.None, OnClientRecieveData, data);
            }

        }

    }
}

Finally we still have to update the flash client now, so that we can allow for the user to type in and submit multiple messages.  For the design I have included the requirement for the last part in this blog post which will be used for data which is sent from the server to the action script client.  This will ultimately lead to the situation where I can pop open multiple flash clients and enable a chat style application using a Flash Client and a C# Server.

Main.as
package 
{
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.ProgressEvent;
	import flash.net.Socket;
	import flash.text.TextField;
	import flash.utils.ByteArray;
	import flash.text.TextFieldType;
	
	/**
	 * ...
	 * @author DefaultUser (Tools -> Custom Arguments...)
	 */
	public class Main extends Sprite 
	{
		//This is the text field which will accept the input from the user
		private var dataEntry:TextField;
		//This is the screen which will be used as the output from the server and the client
		private var console:TextField;
		//This is the button used to initiate the sending of data to the server
		private var button:Sprite;
		
		private var buttonLabel:TextField;
		
		private var consoleHeight:int = 300;
		private var consoleWidth:int = 500;
		
		//The socket which will handle all the communication
		private var socket:BasicSocket;
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		

		private function init(e:Event = null):void 
		{
			//Create the interface
			
			removeEventListener(Event.ADDED_TO_STAGE, init);
			dataEntry = new TextField();
			console = new TextField();
			button = new Sprite
			buttonLabel = new TextField();
			
			console.border = true;
			console.width = consoleWidth;
			console.height = consoleHeight;
			console.x = 50;
			console.y = 50;
			
			dataEntry.border = true;
			dataEntry.multiline = true;
			dataEntry.wordWrap = true;
			dataEntry.type = TextFieldType.INPUT;
			dataEntry.textColor = 0x000000;
			dataEntry.width = consoleWidth - 100;
			dataEntry.height = 100;
			dataEntry.x = 50;
			dataEntry.y = consoleHeight + 50;
			
			buttonLabel = new TextField();
			buttonLabel.text = "SEND";
			
			button.graphics.lineStyle(1, 0x000000);
			button.graphics.drawRoundRect(0, 0, 90, 90, 10, 10);
			button.mouseChildren = false;
			button.buttonMode = true;
			
			button.x = consoleWidth - 40;
			button.y = consoleHeight + 60;
			button.addEventListener(MouseEvent.CLICK, OnSend, false, 0, true);

			buttonLabel.x = ((button.width - buttonLabel.textWidth) / 2) - 2;
			buttonLabel.y = ((button.height - buttonLabel.textHeight) / 2) - 2;
			buttonLabel.mouseEnabled = false;
			
			addChild(console);
			addChild(dataEntry);
			addChild(button);
			button.addChild(buttonLabel);
		}
		
		private function OnSend(e:MouseEvent):void {
			//Send the data to the server
			Send(dataEntry.text);	
			//Clear the text entry box for more data
			dataEntry.text = "";
		}
		
		
		private function Send(data:String):void {
			//If the socket has not yet been initiated
			if (socket == null)
			{
				//Instantiate the socket
				socket = new BasicSocket();
				//Add event listeners for the relevant events we are interested in
				socket.addEventListener(Event.CONNECT, onConnect, false, 0, true);
				socket.addEventListener(Event.CLOSE, onClose, false, 0, true);
				socket.addEventListener(IOErrorEvent.IO_ERROR, onError, false, 0, true);
				socket.addEventListener(ProgressEvent.SOCKET_DATA, OnReceiveData, false, 0 , true);
				//Attempt to conect to the server
				socket.connect("127.0.0.1", 8888);
			}
			//Write the data to the server
			socket.writeUTFBytes(data);
			//Flush the data to the server.  We want to send all of the data to the server whenever
			//this function is called
			socket.flush();
		}
		
		private function OnReceiveData(e:ProgressEvent):void {
			//Read the data from the socket
			var str:String = socket.readUTFBytes(socket.bytesAvailable);
			//Write the data to the console window
			console.appendText(str + "\r\n");
		}
		
		private function onConnect(e:Event):void{
		   console.appendText("connected\r\n");
		}
		 
		private function onClose(e:Event):void{
		   console.appendText("closed\r\n");
		}
		 
		private function onError(e:IOErrorEvent):void{
		   console.appendText("connection error!\r\n");
		}
	}
}

At this stage we are ready to test this client and server so we can simply keep typing and sending the data and this will be output on the server.  No data will appear inside the client as of yet, this will be the final part to this post.  I will use screen toaster again to demo this.

Nearly finished, the flash client and C# TCP Server in action

Accept textual data sent from C# to Flash over TCP using Sockets

So from here we want to send data the other way from the server to the flash client.  The way I will code this is as follows.  I will alter the Server.cs to contain a list of the currently connected client sockets.  Every time a new message is sent to the server, the server will send the message out to all the clients.  This will straight away provide the necessary plumbing to have a multi client chat application, albeit I am using on the same computer, for the moment.

If the client disconnects, we want to remove it from the list, so as the server will not try and send data to a disconnected client.  After all that is complete, we can loop through all the client sockets and begin to send the data.

I will create two new functions inside the server which are involved in sending the data.  The first overload of this method will simply take a string parameter which will be the data it needs to send.  The second overload will take the client socket which originates the message and also the data of that message.  The reason being is that messages may originate from the server as well as other clients.  Both functions will then loop through the list of client sockets and send the data to them.

At this stage, the Action Script Flash client will not change as everything we need for the current time has been coded for, so please find below the nearly finished Simple C# TCP Server code.

Server.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace CSharpTcpServer
{
    /// <summary>
    /// A simple C# TCP Server
    /// </summary>
    public class Server
    {
        private string host;
        private int port;
        private Socket server;
        private List<Socket> clientSockets;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="port">The port for the server to listen for connections on</param>
        public Server(int port)
        {
            //Set the port
            this.port = port;
            //Instantiate the socket for the server and we want to use Streams and TCP
            this.server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //A container for the client connections
            this.clientSockets = new List<Socket>();
        }

        /// <summary>
        /// Method to start the server and wait for the intial client
        /// </summary>
        public void Start()
        {
            //Makesure we can accept a connectoin from any IP but only on port 888
            this.server.Bind(new IPEndPoint(IPAddress.Any, this.port));
            //Allow a maximum backlog of 10 connections
            this.server.Listen(10);
            //Instruct the server to accept the next client connection
            this.server.BeginAccept(OnClientConneced, this.server);

            Console.WriteLine("Server started and waiting for clients...");
        }

        /// <summary>
        /// This will shut down the server and stop any tranmission from and to the server
        /// </summary>
        public void Stop()
        {
            //Makesure the server is connected before attempting to shut it down
            if (this.server.Connected)
            {
                Console.WriteLine("Server Shutting Down...");
                this.server.Shutdown(SocketShutdown.Both);
            }
        }

        /// <summary>
        /// This will be called when a client connected to the server
        /// </summary>
        /// <param name="result">The asyncronous result containing the server socket</param>
        protected void OnClientConneced(IAsyncResult result)
        {
            //Makesure the server is connected before accepting a new client
            if (!this.server.Connected)
            {
                //Cast the state of the Async Result as the Server Socket
                Socket serverSocket = (Socket)result.AsyncState;

                //Ending the Accept method will result in the Socket of the client
                Socket clientSocket = serverSocket.EndAccept(result);

                //Add the client socket to the connection container
                clientSockets.Add(clientSocket);

                //Inform the other clients of the new connection
                SendData(clientSocket, " has connected");

                Console.WriteLine("Client Connected");

                StateObject stateObj = new StateObject(clientSocket, serverSocket);

                clientSocket.BeginReceive(stateObj.Data, 0, StateObject.BUFFER_SIZE,
                    SocketFlags.None, OnClientRecieveData, stateObj);

                //Now we have the client inform the server to continue listening for further clients
                this.server.BeginAccept(OnClientConneced, this.server);
            }
        }

        /// <summary>
        /// When data is received from the client, it is output to the console window.
        /// Currently this function will only read from the input stream once.
        /// </summary>
        /// <param name="result">The asyncronous result containing the server socket and the incoming data</param>
        protected void OnClientRecieveData(IAsyncResult result)
        {
            //Cast the state back to a state object
            StateObject data = (StateObject)result.AsyncState;

            //If the client is not connected then simply return as this session has ended
            if (!data.ClientSocket.Connected)
                return;

            //Ending the async receive method will return the length of bytes in the current chunk
            int dataLength = data.ClientSocket.EndReceive(result);

            //If it is zero then we display a message of client disconnected
            //This is not complete but for the purposes of this stage of the demo this is how it is
            if (dataLength == 0)
            {
                //Remove the disconnected client from the list
                clientSockets.Remove(data.ClientSocket);
                //Inform the other client of the disconnection
                SendData(data.ClientSocket, " has disconnected");
                //Clean up
                data.Dispose();
                //Make the state object null
                data = null;
                Console.WriteLine("Client Disconnected");
            }
            else if (dataLength < StateObject.BUFFER_SIZE)
            {
                //The chunk is less than the size of the buffer which means there are no further chunks
                //inside this transmission

                //Write the data into the stream of the state object to persist it
                data.Stream.Write(data.Data, 0, dataLength);

                //Rewind the stream back the start
                data.Stream.Position = 0;

                //We are assuming that the data being sent is plain text so we can output this to the console
                //window
                string dataToWrite = Encoding.Default.GetString(data.Stream.ToArray());
                //Output the data onto the server
                Console.WriteLine(dataToWrite);
                //Pump out the message so all clients can see the data
                SendData(data.ClientSocket, dataToWrite);

                //Dispose of the data
                data.Dispose();

                //Instantiate a new state object for further transmissions
                data = new StateObject(data.ClientSocket, data.ServerSocket);

                //Instruct the server to wait for more data from the client
                data.ClientSocket.BeginReceive(data.Data, 0, StateObject.BUFFER_SIZE,
                    SocketFlags.None, OnClientRecieveData, data);
            }
            else
            {
                //Write the data to the state object
                data.Stream.Write(data.Data, 0, dataLength);

                //Instruct the server to wait for more data from the client
                data.ClientSocket.BeginReceive(data.Data, 0, StateObject.BUFFER_SIZE,
                    SocketFlags.None, OnClientRecieveData, data);
            }

        }

        
        protected void OnDataSent(IAsyncResult result)
        {
            Socket clientSocket = (Socket)result.AsyncState;

            clientSocket.EndSend(result);
        }

        //The server will use this method when the message has originated from itself
        private void SendData(string data)
        {
            var message = String.Format("{1}", data);

            for (int i = 0; i < clientSockets.Count; i++)
            {
                byte[] dataToSend = Encoding.Default.GetBytes(message);
                if (clientSockets[i].Connected)
                    clientSockets[i].BeginSend(dataToSend, 0, dataToSend.Length, SocketFlags.None, OnDataSent, clientSockets[i]);
            }
        }

        //This will be used the when the server pumps out the messages and the message originated from 
        //the client.
        private void SendData(Socket fromClient, string data)
        {
            var message = String.Format("{0} : {1}", fromClient.RemoteEndPoint, data);

            for (int i = 0; i < clientSockets.Count; i++)
            {
                byte[] dataToSend = Encoding.Default.GetBytes(message);
                if (clientSockets[i].Connected)
                    clientSockets[i].BeginSend(dataToSend, 0, dataToSend.Length, SocketFlags.None, OnDataSent, clientSockets[i]);
            }
        }
    }
}

Serialize and post objects over TCP using XML as the vehicle and TCP as the transport going from Flash to C# and visa-versa

So the final part in this post, is that I want to send an object from Flash to the C# server and also vica versa.  The two languages of course are not interoperable so we have to find a middle ground which in this case will be XML.  It would be brilliant of course to make this use SOAP over TCP, but for the purposes of this demo I will use simple XML, and also as the object I want to send is simple, it will provide a clear, simple, and interoperable way to interface between environments.

The C# Side

For this final part of this post, the C# side requires the most work to get this functioning.  We want to do the following:

  1. Create an Abstract class called Packet
  2. Create a class called XmlPacket which inherits from Packet
  3. Create another another overload of the SendData function which will accept a Packet object
  4. Create a function on the server to Read and Convert the received data into a Packet
  5. Create a function on the server which takes the Packet and sends to the clients

The Flash Side

  1. Create a class called AbstractPacket which all other types of Packets will inherit from
  2. Create a class called XmlPacket which inherits from AbstractPacket
  3. Change the OnReceiveData function to cast the received data into XML
  4. Change the Send function to send the XML to the server.

So the following is the final pieces of the code and also a short screen toaster video showing the application in action.  The code for both the C# App and the Flash client can be found at the start of the post.

Packet.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSharpTcpServer
{
    public abstract class Packet
    {
        public abstract byte[] GetData();
    }
}

XmlPacket.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.ComponentModel;
using System.Xml.Serialization;

namespace CSharpTcpServer
{
    [Serializable]
    [XmlRoot (ElementName="xmlpacket")]
    public class XmlPacket : Packet
    {
        [XmlElement(ElementName="handle")]
        public string Handle { get; set; }
        [XmlElement(ElementName = "date")]
        public DateTime Date { get; set; }
        [XmlElement(ElementName="message")]
        public string Message { get; set; }

        private StringBuilder builder;
        private XmlWriter writer;

        public XmlPacket()
        {

        }

        public override byte[] GetData()
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.ConformanceLevel = ConformanceLevel.Fragment;

            builder = new StringBuilder();
            writer = XmlWriter.Create(builder, settings);

            writer.WriteStartElement("xmlpacket");
            writer.WriteElementString("handle", Handle);
            writer.WriteElementString("date", "2009-06-08");
            writer.WriteElementString("message", Message);
            writer.WriteEndElement();

            writer.Flush();

            return Encoding.Default.GetBytes(builder.ToString());
        }


    }
}

Server.cs

This is the final and updated version of the Server.cs class for the purposes of this post.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Xml.Schema;

namespace CSharpTcpServer
{
    /// <summary>
    /// A simple C# TCP Server
    /// </summary>
    public class Server
    {
        private string host;
        private int port;
        private Socket server;
        private List<Socket> clientSockets;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="port">The port for the server to listen for connections on</param>
        public Server(int port)
        {
            //Set the port
            this.port = port;
            //Instantiate the socket for the server and we want to use Streams and TCP
            this.server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //A container for the client connections
            this.clientSockets = new List<Socket>();
        }

        /// <summary>
        /// Method to start the server and wait for the intial client
        /// </summary>
        public void Start()
        {
            //Makesure we can accept a connectoin from any IP but only on port 888
            this.server.Bind(new IPEndPoint(IPAddress.Any, this.port));
            //Allow a maximum backlog of 10 connections
            this.server.Listen(10);
            //Instruct the server to accept the next client connection
            this.server.BeginAccept(OnClientConneced, this.server);

            Console.WriteLine("Server started and waiting for clients...");
        }

        /// <summary>
        /// This will shut down the server and stop any tranmission from and to the server
        /// </summary>
        public void Stop()
        {
            //Makesure the server is connected before attempting to shut it down
            if (this.server.Connected)
            {
                Console.WriteLine("Server Shutting Down...");
                this.server.Shutdown(SocketShutdown.Both);
            }
        }

        /// <summary>
        /// This will be called when a client connected to the server
        /// </summary>
        /// <param name="result">The asyncronous result containing the server socket</param>
        protected void OnClientConneced(IAsyncResult result)
        {
            //Makesure the server is connected before accepting a new client
            if (!this.server.Connected)
            {
                //Cast the state of the Async Result as the Server Socket
                Socket serverSocket = (Socket)result.AsyncState;

                //Ending the Accept method will result in the Socket of the client
                Socket clientSocket = serverSocket.EndAccept(result);

                //Add the client socket to the connection container
                clientSockets.Add(clientSocket);

                //Inform the other clients of the new connection
                SendData(clientSocket, " has connected");

                Console.WriteLine("Client Connected");

                StateObject stateObj = new StateObject(clientSocket, serverSocket);

                clientSocket.BeginReceive(stateObj.Data, 0, StateObject.BUFFER_SIZE,
                    SocketFlags.None, OnClientRecieveData, stateObj);

                //Now we have the client inform the server to continue listening for further clients
                this.server.BeginAccept(OnClientConneced, this.server);
            }
        }

        /// <summary>
        /// When data is received from the client, it is output to the console window.
        /// Currently this function will only read from the input stream once.
        /// </summary>
        /// <param name="result">The asyncronous result containing the server socket and the incoming data</param>
        protected void OnClientRecieveData(IAsyncResult result)
        {
            //Cast the state back to a state object
            StateObject data = (StateObject)result.AsyncState;

            //If the client is not connected then simply return as this session has ended
            if (!data.ClientSocket.Connected)
                return;

            //Ending the async receive method will return the length of bytes in the current chunk
            int dataLength = data.ClientSocket.EndReceive(result);

            //If it is zero then we display a message of client disconnected
            //This is not complete but for the purposes of this stage of the demo this is how it is
            if (dataLength == 0)
            {
                //Remove the disconnected client from the list
                clientSockets.Remove(data.ClientSocket);
                //Inform the other client of the disconnection
                SendData(data.ClientSocket, " has disconnected");
                //Clean up
                data.Dispose();
                //Make the state object null
                data = null;
                Console.WriteLine("Client Disconnected");
            }
            else if (dataLength < StateObject.BUFFER_SIZE)
            {
                //The chunk is less than the size of the buffer which means there are no further chunks
                //inside this transmission

                //Write the data into the stream of the state object to persist it
                data.Stream.Write(data.Data, 0, dataLength);

                //Rewind the stream back the start
                data.Stream.Position = 0;

                //We are assuming that the data being sent is plain text so we can output this to the console
                //window
                
                //string dataToWrite = Encoding.Default.GetString(data.Stream.ToArray());

                XmlPacket packetFromClient = GetDataPacket(data.Stream);

                Console.WriteLine("{0} [{1}] : {2}", packetFromClient.Handle, packetFromClient.Date, packetFromClient.Message);

                //Output the data onto the server
                //Console.WriteLine(dataToWrite);

                //Pump out the message so all clients can see the data
                SendData(data.ClientSocket, packetFromClient);

                //Dispose of the data
                data.Dispose();

                //Instantiate a new state object for further transmissions
                data = new StateObject(data.ClientSocket, data.ServerSocket);

                //Instruct the server to wait for more data from the client
                data.ClientSocket.BeginReceive(data.Data, 0, StateObject.BUFFER_SIZE,
                    SocketFlags.None, OnClientRecieveData, data);
            }
            else
            {
                //Write the data to the state object
                data.Stream.Write(data.Data, 0, dataLength);

                //Instruct the server to wait for more data from the client
                data.ClientSocket.BeginReceive(data.Data, 0, StateObject.BUFFER_SIZE,
                    SocketFlags.None, OnClientRecieveData, data);
            }

        }

        
        protected void OnDataSent(IAsyncResult result)
        {
            Socket clientSocket = (Socket)result.AsyncState;

            clientSocket.EndSend(result);
        }

        //The server will use this method when the message has originated from itself
        private void SendData(string data)
        {
            var message = String.Format("{1}", data);

            for (int i = 0; i < clientSockets.Count; i++)
            {
                byte[] dataToSend = Encoding.Default.GetBytes(message);
                if (clientSockets[i].Connected)
                    clientSockets[i].BeginSend(dataToSend, 0, dataToSend.Length, SocketFlags.None, OnDataSent, clientSockets[i]);
            }
        }

        //This will be used the when the server pumps out the messages and the message originated from 
        //the client.
        private void SendData(Socket fromClient, Packet data)
        {
            //var message = String.Format("{0} : {1}", fromClient.RemoteEndPoint, data);

            for (int i = 0; i < clientSockets.Count; i++)
            {
                byte[] dataToSend = data.GetData(); //Encoding.Default.GetBytes(message);
                if (clientSockets[i].Connected)
                    clientSockets[i].BeginSend(dataToSend, 0, dataToSend.Length, SocketFlags.None, OnDataSent, clientSockets[i]);
            }
        }

        private void SendData(Socket fromClient, string data)
        {
            var message = String.Format("{0} : {1}", fromClient.RemoteEndPoint, data);

            for (int i = 0; i < clientSockets.Count; i++)
            {
                byte[] dataToSend = Encoding.Default.GetBytes(message);
                if (clientSockets[i].Connected)
                    clientSockets[i].BeginSend(dataToSend, 0, dataToSend.Length, SocketFlags.None, OnDataSent, clientSockets[i]);
            }
        }

        /// <summary>
        /// Deserializes the stream back into a XML Packet so it can be read and processed by the server
        /// </summary>
        /// <param name="data">The data sent from the client</param>
        /// <returns>XmlPacket</returns>
        private XmlPacket GetDataPacket(Stream data)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(XmlPacket));
            Console.WriteLine(Encoding.Default.GetString(((MemoryStream)data).ToArray()));

            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ValidationFlags = XmlSchemaValidationFlags.None;
            settings.ValidationType = ValidationType.None;
            settings.ConformanceLevel = ConformanceLevel.Fragment;
            settings.IgnoreProcessingInstructions = true;
            settings.NameTable = new NameTable();
            settings.NameTable.Add("");
            XmlReader reader = XmlReader.Create(data, settings);  

            XmlPacket packet = (XmlPacket)serializer.Deserialize(reader);

            return packet;
        }

        private byte[] GetDataFromPacket(XmlPacket packet)
        {
            return packet.GetData();
        }
    }
}

The GetDataPacket function of the Server handles the deserialization of the data for you in a clean and efficient way.  One key aspect of the XmlPacket class is that the root attribute only stores the element name and not the namespace as, like you can see in the following action script class we do not give a namespace to the data structure so we can avoid any parsing errors of the XML.

I write out the data sent to the server just for debugging purposes so you can see the format of the data when it arrives.  You will also notice that I have hard coded the date into the XML Structure.  This is not for any particular reason other than at the time of writing I have not found or written a function in Action Script which will give me the CC in the date format, as this seems to be a requirement when sending the XML to the server over the TCP.

So finally the three peices of the ActionScript.

AbstractPacket.as

package  
{
	import flash.utils.ByteArray;
	
	/**
	 * ...
	 * @author Andrew Rea
	 */
	public class AbstractPacket 
	{
		
		public function AbstractPacket() 
		{
			
		}
		
		public function GetData():ByteArray {
			//Available for override
			throw new Error("Must be overridden");
		}
	}
	
}

XmlPacket.as

package  
{
	import flash.utils.ByteArray;
	
	/**
	 * ...
	 * @author Andrew Rea
	 */
	public class XmlPacket extends AbstractPacket
	{
		private var _handle:String;
		private var _date:Date = new Date();
		private var _message:String;
		
		private var _xml:XML
								
									
		
		public function XmlPacket() 
		{
			
		}
		
		public override function GetData():ByteArray 
		{
			_date = new Date();
			_xml = <xmlpacket>
					< handle > { _handle }</handle>
					< date > 2009-06-08</date>
					< message > { _message }</message>
				</xmlpacket>;
								
			var byteData:ByteArray = new ByteArray();
			byteData.writeUTFBytes(_xml.toXMLString());
			byteData.position = 0;
			return byteData;
		}

		/**
		 * A great way to include cdata section into the XML where you want to inject variables
		 * @param	theURL
		 * @return
		 */
		function cdata(theURL:Date):XML
		{
		var x:XML = new XML("<![CDATA[" + theURL + "]]>"); 
		return x;
		}
		
		public function set Handle(value:String):void {
			_handle = value;
		}
		
		public function get Handle():String {
			return _handle;
		}
		
		public function set DateValue(value:Date):void {
			_date = value;
		}
		
		public function get DateValue():Date {
			return _date;
		}
		
		public function set Message(value:String):void {
			_message = value;
		}
		
		public function get Message():String {
			return _message;
		}
	}
	
}

Main.as

package 
{
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.ProgressEvent;
	import flash.net.Socket;
	import flash.text.TextField;
	import flash.utils.ByteArray;
	import slideshow.event.PageChangeEvent;
	import flash.text.TextFieldType;
	
	/**
	 * ...
	 * @author DefaultUser (Tools -> Custom Arguments...)
	 */
	public class Main extends Sprite 
	{
		//This is the text field which will accept the input from the user
		private var dataEntry:TextField;
		//This is the screen which will be used as the output from the server and the client
		private var console:TextField;
		//This is the button used to initiate the sending of data to the server
		private var button:Sprite;
		
		private var buttonLabel:TextField;
		
		private var consoleHeight:int = 300;
		private var consoleWidth:int = 500;
		
		//The socket which will handle all the communication
		private var socket:BasicSocket;
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		

		private function init(e:Event = null):void 
		{
			//Create the interface
			
			removeEventListener(Event.ADDED_TO_STAGE, init);
			dataEntry = new TextField();
			console = new TextField();
			button = new Sprite
			buttonLabel = new TextField();
			
			console.border = true;
			console.width = consoleWidth;
			console.height = consoleHeight;
			console.x = 50;
			console.y = 50;
			
			dataEntry.border = true;
			dataEntry.multiline = true;
			dataEntry.wordWrap = true;
			dataEntry.type = TextFieldType.INPUT;
			dataEntry.textColor = 0x000000;
			dataEntry.width = consoleWidth - 100;
			dataEntry.height = 100;
			dataEntry.x = 50;
			dataEntry.y = consoleHeight + 50;
			
			buttonLabel = new TextField();
			buttonLabel.text = "SEND";
			
			button.graphics.lineStyle(1, 0x000000);
			button.graphics.drawRoundRect(0, 0, 90, 90, 10, 10);
			button.mouseChildren = false;
			button.buttonMode = true;
			
			button.x = consoleWidth - 40;
			button.y = consoleHeight + 60;
			button.addEventListener(MouseEvent.CLICK, OnSend, false, 0, true);

			buttonLabel.x = ((button.width - buttonLabel.textWidth) / 2) - 2;
			buttonLabel.y = ((button.height - buttonLabel.textHeight) / 2) - 2;
			buttonLabel.mouseEnabled = false;
			
			addChild(console);
			addChild(dataEntry);
			addChild(button);
			button.addChild(buttonLabel);
		}
		
		private function OnSend(e:MouseEvent):void {
			//Send the data to the server
			//Send(dataEntry.text);	
			
			var packet:XmlPacket = new XmlPacket();
			packet.Handle = "REA_ANDREW";
			packet.Message = dataEntry.text;
			Send(packet);
			
			//Clear the text entry box for more data
			dataEntry.text = "";
		}
		
		
		private function Send(data:AbstractPacket):void {
			//If the socket has not yet been initiated
			if (socket == null)
			{
				//Instantiate the socket
				socket = new BasicSocket();
				//Add event listeners for the relevant events we are interested in
				socket.addEventListener(Event.CONNECT, onConnect, false, 0, true);
				socket.addEventListener(Event.CLOSE, onClose, false, 0, true);
				socket.addEventListener(IOErrorEvent.IO_ERROR, onError, false, 0, true);
				socket.addEventListener(ProgressEvent.SOCKET_DATA, OnReceiveData, false, 0 , true);
				//Attempt to conect to the server
				socket.connect("127.0.0.1", 8888);
			}
			
			var byteData:ByteArray = data.GetData();
			
			//Write the data to the server
			socket.writeBytes(byteData, 0, byteData.length);
			//Flush the data to the server.  We want to send all of the data to the server whenever
			//this function is called
			socket.flush();
		}
		
		private function OnReceiveData(e:ProgressEvent):void {
			//Read the data from the socket
			var data:XML = new XML(socket.readUTFBytes(socket.bytesAvailable));
			//Write the data to the console window
			console.appendText("[" + data.handle +"] : " + data.message + "\r\n");
		}
		
		private function onConnect(e:Event):void{
		   console.appendText("connected\r\n");
		}
		 
		private function onClose(e:Event):void{
		   console.appendText("closed\r\n");
		}
		 
		private function onError(e:IOErrorEvent):void{
		   console.appendText("connection error!\r\n");
		}
	}
}

So this here ends the first part in the series which I am writing on Socket Communication between various languages both being used as both the server and the client in most instances.  This post has dealt with C# holding the server side of the bargain and flash having the client role.  There are also some variations of each which I want to make including doing the above but using WCF and TCP for the server part of the application.

Cheers for now.

Andy


Tuesday, June 09, 2009 2:10:01 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer

FlashDevelop IDE Project Source for sample application here
Working Example here

image

So I followed the three video tutorials here:

  1. http://theflashblog.com/?p=705
  2. http://theflashblog.com/?p=744
  3. http://theflashblog.com/?p=804

Lee Brimelow, the author, composed this inside Adobe Flex Builder 3.0 which is commercial and has a trial but ultimately you have to purchase.  I used FlashDevelop IDE to create the same small APP, and I have no complaints.  The biggest difference you will experience is not having design time support for the interface.  This is not an issue for me on a few levels but primarily because I am not a designer and programmatic layout is fine for me.

Watching the third tutorial in the series I found out about an amazing site called ScaleNine.  It is a community based site with designers skinning the component set provided by flex, and outputs the application to look like the above.  The normal default flex look is like this:

image

I, and I think you the reader will also prefer the above to the default one.  Using FlashDevelop IDE and the Flex SDK you can develop Flex applications totally free, with no over head apart from hosting your application somewhere.  With the FlashDevelop IDE you can also develop Adobe AIR applications which is what i want to try next.  Ultimately you will need to get learning Action Script 3.0 but once on your way, it is a really nice language to work with.  If you come from a C++, Java or C# background then the syntax will be a breeze.  The event model is similar to Java whilst Action Script 3.0 harness get and set keywords like C#.

Click here to get the Flash Develop IDE
Click here to get the Adobe Flex SDK

Cheers,

Andrew


Monday, March 16, 2009 11:13:56 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer

For developing Flash and Flex projects I use Flash Develop.  It is a lightweight, fast IDE to use for Action Script development and also some other languages.  You can find the project and downloads here:

http://www.flashdevelop.org/community/

So back to topic, when you create a new project, for example I will select a new Action Script 3 project, you will definitely want to enable tracing in your application to aid with debugging.  To get this done you first need to hop over to adobe and download the debug version of the Flash Projector and whilst there, there is no harm in getting the Browser plug-in too.  The location is here:

http://www.adobe.com/support/flashplayer/downloads.html

Once downloaded and installed, it has placed a debug exe in your Adobe Folder inside program files.  So based on this, going back to the IDE, you need to:

  • Go to the Program Settings:

image

  • Then navigate to the Flash Viewer menu tab

image

I have set my external player path as: C:\Program Files\Adobe\Adobe Flash CS4\Players\Debug\FlashPlayer.exe .  If yours differs just make sure that you simply browse and select the debug player you downloaded.

Using the trace statements will then be recorded.  P.s. not quite sure what difference the Movie Display Style makes but it obviously does something.  It is not a concern for me at present so I have not investigated.

Cheers,

Andrew


Friday, February 06, 2009 8:28:54 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer

A comparison with other languages to .NET during my programming experiences.

I like to bring a .NET programming naming convention to my other programming in different languages e.g. parameters, local variables, interfaces, functions etc...

Of late I am programming in Java more and more, as an accompaniment to my current programming skill set and by no means a substitution.  What I mean is that I am offering Java now as one of my skill set, if it fits a clients specification, so in essence giving me more tools and the client more options.

I would like to point out one observation though from the outset. 

As my background is from .NET and Microsoft managed languages, I am constantly making adhoc comparisons, judgements, evaluations etc... between the two.

  • Hmmm I like that idea, or
  • Nah that's good but I prefer the way they do it in ... or
  • Hey that's cool, both have opted to go they same way on that one!

So basically my likes, dislikes, wants, unknowns and general observations of equality. so below I have grouped a few observations so far.

Interfaces

I definitely prefer to prefix my interfaces with the uppercase I, i.e. IMyInterface as opposed to simply MyInterface.  So when I am coding I use the I prefix for my interfaces, as I like the immediate and obvious differentiation between an interface and class object.

In Java you have to specify public scope for your methods, where as in C# this is not allowed and it is presumed that the coder understands any methods WILL BE public.  I am on the fence on this one as I can see benefits for both.

Properties

I like the getter and setter convention in C#, including the new shortcuts in .NET 3.5 which describe properties, e.g.

public string MyProperty{get;set;}

or

public string MyProperty{
	get{return myProperty;}
	set{myProperty = value;}
}

Method Overloading

This is a like I had from ActionScript, and one which I have read WILL be implemented in C# 4.0, and I am not sure of its name but i call it Dynamic Method Overloading.  In ActionScript you are able to provide the paramaters of a method's signature with default values.  So for example say you have ONE method with TWO parameters and the second one having a default parameter e.g.

public int MyMethod(int firstArg, int secondArg = 2)
{
	Add(firstArgs,secondArg);
}

I could then call this function like so:

int value1 = MyMethod(10); //Result would be 12
int value2 = MyMethod(10,10) //Result would be 20

So you can see in the first invocation I only supply one parameter, yet what is returned is the first parameter and also the second parameter added together as per the method's instruction.

Namespace Import

This is not a like or dislike but rather an observation of dissimilarity.  If I want to import all classes from the System.Net namespace inside .NET I can do just that by saying using System.Net yet in Java I must suffix with an asterisk, and one of the reason I can understand as to the reason is that you can import single classes as opposed to their namespace or package. For example I could specify an import for a JCheckBox itself in Java i.e.

import javax.swing.JCheckBox;

I could not do the same in C#, for example the following is not correct:

using System.Net.Sockets.Socket;

Again I neither like or dislike both of them but I think the difference is ironically large and small at the same time.

Event Model

I will be publishing a post about this topic individually in which I will describe events using a model a showing the relevant counterparts of C#, Java and ActionScript.  I have not yet got the knowledge to produce a C++ example so if anyone reading could and kindly would not mind, I would greatly appreciate the input.

Each of the following are what I feel I need to focus on in the blog post for each language by way of how they implement an Observer Pattern or Events.

In Java there are a the following to focus on which have slightly different uses but ultimately for the same purpose which is notification of change or action.

  • Observer
  • Observerable
  • EventObject
  • EventListener

In C# I need to focus on:

  • Delegates
  • EventHandlers
  • Event
  • Chaining Invocation

In ActionScript I would focus on:

  • The Event Object
  • The IEventDispatcher Interface

I will use an example for the above languages and a few events a car emits which will show the different implementations of the above.

Class Naming Conventions

Both Java and ActionScript require the name of the file to equal the name of the class.  C# on the other hand does not have this requirement.  I would assume that this is because in C# I am able to put more than one class in a .cs file, and by that I do not mean nesting.  In Java and ActionScript I can nest classes inside others but I cannot start a new class declaration in the same file after one has already been declared.  Personally I agree with the Java implementation and would like to see each class in its own file if not required to nest.

That being said though I think that Partial Classes in .NET are such a good IDEA and a great piece of architectural planning and implementation.

Tis all for now lol.



ActionScript | C# | Java
Tuesday, January 27, 2009 10:56:48 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer