Peer-to-peer Chat Program using Asynchronous Socket

This is an update to the previous code post on 03/22/2002. In the update, I include the sending and receiving function. The sending and receiving file is based on my own command that can modify according to u requirement. The concept is descript as below: 
Actually, u can base on this kind of command to do a lot of stuff like searching file remotely, check remote PC information and other u can think of.

This is a simple chat program, which uses asynchronous socket to provide connection between two machines. This program acts as a client/server, which can get connected to other PCs (installed with same program) or wait for other PC to connect. You can even test this program on a single PC by running the program twice. Each instance of the program listens to a port (e.g. first instance listens to port 998 and the second instance listens to port 999). Click the listen button of both instances, enter the hostname/Host IP Address as "local" or "" and Port no as 999 for the first instance (cause we want to connect to the second instance, which listens to port 999), click connect. The IP address will list 2 program (if successfully connected). At this point, you can start sending messages.
In this program, I also demonstrated how the events are raised during connection, disconnection, sending and receiving (like the OnConnect, OnSend... in MSVC++ MFC's socket class).

I have created a class named WSocket (not inherit from Socket class). The public Socket object is Soc, which do all the socket tasks. I can't inherit from Socket class, cause when the Accept()/EndAccept() method in the Socket

Sending Client Server Receiving
Send Filename and size to Accepted the file detail
Send signal back, tell client to start sending
Once signal is received, start sending file data. (Block by block until end of file)  Store to file.
 Done Successfully received all

base only return Socket object and causes casting problem (as shown here)

public void AcceptCallback(IAsyncResult ar)
WSocket listener = (WSocket) ar.AsyncState;
WSocket myNewSoc = (WSocket)listener.EndAccept(ar);
//Cause casting won't work

The purpose of WSocket class is to provide some custom events or some extra task ( u can add your functionality to the class if you want). First, it will be listening for the socket which keep on waiting for other PC to connect, once the remote client is calling, the listening socket will raised the AcceptCallback() function, and the accepted socket will put in the available WSocket array.

WSocket listener = (WSocket) ar.AsyncState;
int nSoc = GetAvailbleSocket();
SocClient[nSoc].Soc = (Socket)ListenSoc.Soc.EndAccept(ar);
accepted socket
SocClient[nSoc].SockRefNo = nSocRef;
//keep the array refno

Any suggestion, amendment or comment is welcome, cause i still new in C#. Together we learn, together we grow.