Profilo di DexterC# Network library proje...FotoBlogElenchi Strumenti Guida

Blog


22 novembre

NAT Traversal in .NET Framework Version 4


I've just installed MSVS 2010 Beta 2 and this is just one of the surprise thats interest me on what's new on .NET Framework Version 4 particularly on networking. Taken from MSDN:


NAT Traversal using IPv6 and Teredo

Enhancements were made that provide support for Network Address Translation (NAT) traversal. These changes are designed for use with IPv6 and Teredo, but they are also applicable to other IP tunneling technologies. These enhancements affect classes in the System.Net and related namespaces.

These changes can affect client and server applications that plan to use IP tunneling technologies.

The changes to support NAT traversal are available only for applications using .NET Framework version 4. These features are not available on earlier versions of the .NET Framework.

Overview

The Internet Protocol version 4 (IPv4) defined an IPv4 address as 32 bits long. As a result, IPv4 supports approximately 4 billion unique IP addresses (2^32). As the number of computers and network devices on the Internet expanded in the 1990s, the limits of the IPv4 address space became apparent.

One of several techniques used to extend the lifetime of IPv4 has been to deploy NAT to allow a single unique public IP address to represent a large number of private IP addresses (private Intranet). The private IP addresses behind the NAT device share the single public IPv4 address. The NAT device may be a dedicated hardware device (an inexpensive Wireless Access Point and router, for example) or a computer running a service to provide NAT. A device or service for this public IP address translates IP network packets between the public Internet and the private Intranet.

This scheme works well for client applications running on the private Intranet that send requests to other IP addresses (usually servers) on the Internet. The NAT device or server can keep a mapping of client requests so when a response is returned it knows where to send the response. But this scheme poses problems for applications running in the private Intranet behind the NAT device that want to provide services, listen for packets, and respond. This is particularly the case for peer-to-peer applications.

The IPv6 protocol defined an IPv4 address as 128 bits long. As a result, IPv6 supports very a large IP address space of 3.2 x 10^38 unique addresses (2^128). With an address space of this size, it is possible for every device connected to the Internet to be given a unique address. But there are problems. Much of the world is still using only IPv4. In particular, many of the existing routers and wireless access points used by small companies, organizations, and households do not support IPv6. Also some Internet service providers that serve these customers either do not support or have not configured support for IPv6.

Several IPv6 transition technologies have been developed to tunnel IPv6 addresses in an IPv4 packet. These technologies include 6to4, ISATAP, and Teredo tunnels that provide address assignment and host-to-host automatic tunneling for unicast IPv6 traffic when IPv6 hosts must traverse IP4 networks to reach other IPv6 networks. IPv6 packets are sent tunneled as IPv4 packets. Several tunneling techniques are being used that allow NAT traversal for IPv6 addresses through a NAT device.

Teredo is one of the IPv6 transition technologies which brings IPv6 connectivity to IPv4 networks. Teredo is documented in RFC 4380 published by the Internet Engineering Task Force (IETF). Windows XP SP2 and later provide support for a virtual Teredo adapter which can provide a public IPv6 address in the range 2001:0::/32. This IPv6 address can be used to listen for incoming connections from the Internet and can be provided to IPv6 enabled clients that wish to connect to the listening service. This frees an application from worrying about how to address a computer behind a NAT device, since the application can just connect to it using its IPv6 Teredo address. 


22 settembre

Do you hear what I hear? Silver bells, Silver bells...

 
Do You Hear What I Hear? although, it's already September  and the start of *BER months means it's Christmas season, It's not a Christmas song that I'm referring to Wink Frankly I didn't see this coming, did you hear or have you heard the Silvelight support for TCP Socket.
 
Taken from MSDN:
 
"The System.Net.Sockets namespace in Silverlight version 3 provides a managed implementation of the sockets networking interface for developers who need to tightly control access to the network. On Windows, the System.Net.Sockets namespace provides a managed implementation of the Windows Sockets (Winsock) interface. On Apple Mac OS X, the  System.Net.Sockets namespace provides a managed implementation of the sockets interface based on Berkeley Software Distribution (BSD) UNIX."
 
One additional restriction on using the sockets classes is that the destination  port range that a network application is allowed to connect to must be within the range of 4502-4534. These are the only destination ports allowed by a connection from a Silverlight application using sockets. If the target port is not within this port range, the attempt to connect will fail. It is possible for a target server to receive connections on a port from this restricted range and redirect it to a different port (a well-known port, for example) if this is needed to support a  specific existing application protocol.
 
To deploy a security policy file on a server for sockets, system administrators need  to configure a separate authentication service on port 943 for each IP address that is  to provide the policy file definition. 
 
 
This is cool since I didn't omit the TCP support in my network library, including support for asynchronous sending and receiving operations.
 
 
29 settembre

What to send and how?


What kinds of data I can send using Z-Communicator?  Well, the most common things comes to my mind is sending text messages, but that's not the only thing I need to send particularly in games, I also need to send int, float,bool etc... Ok, for this kind of data I created a Meta data type to send group of  fields with different kinds of data type in any order, I can also send raw bytes and serialized object, It can easily done by using the following data writers as shown below.

The sender manager members:

SenderMngr.PNG

Complete Overview

 

Data writers class members:

DataWriters.JPG



//!*>>> Prepares data writers..
//
ZNC.TextDataWriter     _TextDataWriter   =  new ZNC.TextDataWriter();     _TextDataWriter.SetDefault();
ZNC.MetaDataWriter    _MetaDataWriter   =  new ZNC.MetaDataWriter();    _MetaDataWriter.SetDefault();
ZNC.BytesDataWriter   _ByteDataWriter   =  new ZNC.BytesDataWriter();   _ByteDataWriter.SetDefault();
ZNC.ObjectDataWriter  _ObjDataWriter    =  new ZNC.ObjectDataWriter();  _ObjDataWriter.SetDefault();


// Sample user defined game commands, for the recipient to understand what the message is all about.
int _CHAT              = 50;
int _ENTITY_MPOS  = 51;
int _ENTITY_OPOS  = 52;

// Just for this simple example, I'll send the data to the first player at the lobby.
uint m_PlayerUID = _Server.LobbyMngr.GetPlayer(0).PlayerUID;




//!*>>>  S E N D I N G   T E X T   D A T A
//               
//  User defined game command
_TextDataWriter.Command  = _CHAT;
//
// Writing text data.
_TextDataWriter.TEXTDATA = "Hello";
//
// Sending text data using _TextDataWriter.
_Server.SenderMngr.SendTextData(  _TextDataWriter, 
m_PlayerUID,   false, false, false  );




//!*>> > S E N D I N G   M E T A   D A T A
//
//  Sample meta data.

int           m_Status   = 1;
XF.Point    m_Pos      = new XF.Point( 100, 100 );
float         m_VelX     = 0.2f;
float         m_VelY     = 0;
float         m_Speed   = 0.05f;
//
// User defined game command
_MetaDataWriter.Command   = _ENTITY_MPOS;
//
// Writing meta data
_MetaDataWriter.BeginWriteMetaData();
     _MetaDataWriter.WriteData( m_Status   );
     _MetaDataWriter.WriteData( m_Pos       );
     _MetaDataWriter.WriteData( m_VelX      );
     _MetaDataWriter.WriteData( m_VelY      );
     _MetaDataWriter.WriteData( m_Speed    );
_MetaDataWriter.EndWriteMetaData();
//
// Sending meta data using _MetaDataWriter.

_Server.SenderMngr.SendMetaData(  _MetaDataWriter, m_PlayerUID,  false,false,false  );




//!*>>> S E N D I N G   R A W B Y T E S   D A T A
//               

// Sample bytes data.
string m_ConvertMe   = "Send me as bytes";               
//
// Game user defined command
_BytesDataWriter.Command    = 0;
//
// Writing raw bytes.
_ByteDataWriter.BYTESDATA = STE.ASCII.GetBytes(  m_ConvertMe.ToCharArray()  );
//
// Sending raw bytes using _ByteDataWriter.
_Server.SenderMngr.SendBytesData(  _ByteDataWriter, m_PlayerUID,  false, false, false  );




//!*>>>  S E N D I N G   O B J E C T   D A T A
//
// Sample serialized object class. 

SerialObj m_SerialObj = new SerialObj();
//
m_SerialObj.Status  = 1;
m_SerialObj.Pos      = new XF.Point( 100, 100 );
m_SerialObj.VelX     = 0.2f;
m_SerialObj.VelY     = 0;
m_SerialObj.Speed   = 0.05f;
//
// User defined game command
_ObjDataWriter.Command       = _ENTITY_OPOS;
//
// Writing object data.

_ObjDataWriter.OBJECTDATA = m_SerialObj;
//
// Sending object data using _ObjDataWriter.
_Server.SenderMngr.SendObjectData(  _ObjDataWriter, m_PlayerUID,  false, false, false  );




That's how easy it is to send text, meta data, bytes and object data types to the recipient, the samples above uses only the sending overload on a particular client, tho, I can also send data to all or selected player/s at the lobby, send to all or selected player/s on a particular game, send to all or selected player/s on a particular game session and even send to all or selected players/s on a particular zone or area in just a single line, as shown below :


//! Sample single and selected player's UID list..
uint   m_PlayerUID = 1001;
uint[] m_PListUIDS = new uint[] { 1001,1002,1003 };

_TextDataWriter.TEXTDATA = "Hello";

// Say hello to all players. 
_Server.SenderMngr.SendTextData(  _TextDataWriter, 
false, false, false  );
// Say hello to a particular player
.
_Server.SenderMngr.SendTextData(  _TextDataWriter, 
m_PlayerUID,   false, false, false  );
// Say hello to selected  players.
_Server.SenderMngr.SendTextData(  _TextDataWriter, 
m_PListUIDS,   false, false, false  );

// Say hello to all player on  a particular game.
_Server.SenderMngr.SendTextData(  _TextDataWriter,  ZNE.SendTo.PlayerOnGame,     
m_GameUID,  null, false, false, false );
// Say hello to selected players on a particular game
.
_Server.SenderMngr.SendTextData(  _TextDataWriter,  ZNE.SendTo.PlayerOnGame,     
m_GameUID,  m_PListUIDS,  false, false, false  );

// Say hello to all player on  a particular session.
_Server.SenderMngr.SendTextData(  _TextDataWriter,  ZNE.SendTo.PlayerOnSession, 
m_SessionUID null, false, false, false );
// Say hello to selected players on a particular session
.
_Server.SenderMngr.SendTextData(  _TextDataWriter,  ZNE.SendTo.PlayerOnSession, 
m_SessionUID,  m_PListUIDS, false, false, false  );

// Say hello to all player on  a particular zone or area.
_Server.SenderMngr.SendTextData(  _TextDataWriter,  ZNE.SendTo.PlayerOnZone,       
m_ZoneUID,  null, false, false, false );
// Say hello to selected players on a particular zone or area
.
_Server.SenderMngr.SendTextData(  _TextDataWriter,  ZNE.SendTo.PlayerOnZone,     
m_ZoneUID,  m_PListUIDS,  false, false, false );






07 settembre

What's inside the message?

 
 
Before I'll tackle how to grant access to a connecting client or denied the request, I will fast forward a little bit and
talk about how to read messages received by the server.
 
Since I want Z-Communicator optimized on the receiving part behind the scene, at the socket level where the actual
receiving of packets is happening, other than that, there is no need to implement events or delegates on using
Z-Communicator, everything happening at the socket level will be reported via messaging.
 
Like for instance, If the server receives an incomming connection, a connected client requesting to create/join/leave
a game session or client asking for a gracefull disconnection, etzetera... etzetera... I will received an informative
message data from the server message manager "_Server.MessageMngr", and take appropriate action for that
particular message.
 
Z-Communicator have it's own custom data message type format, than just throwing a raw bytes coming from socket,
the received bytes format should conform with the custom format the system have, if the received bytes format does
not conform in any of the available message format it will be discarded and record it to the logger manager, telling
me that an alien bytes format  is  trying to get into the system  Wink sort of data validation and for some
security purposes at the same time. my implementation assures the that if I got a message it's an informative one
and not a garbage data Tongue out.
 
 
Message manager members:
MessageMngr
 
 
To be able to read messages from the message manager,  a simple steps are need to be  implemented,
just create a network message processing routine/method,  which  will be call  from  the main program
on every game update cycle,  in reference from above image, this is how to implement it  in code:
 
1. Begin reading messages.
2. Loop while there is available message to read. 
3. Read the message.
5. Process message base on message type.
6. End reading messages.
 
 
 
/// _____________________________________________________________
/// <summary>
/// N E T W O R K   M E S S A G E    P R O C E S S I N G
/// </summary>
public voidl ProcessNetworkMessages()
{

 
     //!* 1). Begin reading messages.
     _Server.MessageMngr.BeginReadMessage();
 
 
         
     //!* 2). Keep reading all available message received.
     while(  _Server.MessageMngr.MessageIsAvailable()  )
     {
 
 
 
              //!* 3). Read the message
              ZNC.Message m_Message = _Server.MessageMngr.ReadMessage();
 
 
 
              //!* 4). Process message package DATA, base on message type.
              switch ( m_Message.MessageType )
             {
 
 
 
                   //!* SYSTEM SPECIFIC-MESSAGE DATA TYPES:
               
                //!* System data message type
               case ZNE.MessageType.SYSDATA:
                      //!
                      this.ProcessSysDataMessage( m_Message ); break;
 
                    
 
                   //!* GAME SPECIFIC- MESSAGE DATA TYPES:
 
               //!* Meta data message type
               case ZNE.MessageType.METADATA:
                      //!
                     this.ProcessMetaDataMessage( m_Message ); break;
 
               //!* Text data message type
               case ZNE.MessageType.TEXTDATA:
                      //!
                      this.ProcessTextDataMessage( m_Message ); break;
 
               //!* Object data message type
               case ZNE.MessageType.OBJDATA:
                      //!
                      this.ProcessObjDataMessage( m_Message ); break;
 
               //!* Raw bytes data message type
               case ZNE.MessageType.BYTESDATA:
                      //!
                      this.ProcessRawBytesDataMessage( m_Message ); break;
 
               //!* Voice data message type: ( under development )
               case ZNE.MessageType.VOICEDATA:
                      //!
                      this.ProcessVoiceDataMessage( m_Message ); break;
 
 
 
                  //!* FILE HANDLING SPECIFIC-MESSAGE DATA TYPES:
 
                  //!* File data transfer, message advisory.
               case ZNE.MessageType.FILEDATA:
                      //!
                      this.ProcessFileDataMessage( m_Message ); break;
 
                  //!* Download file from web, message advisory.
               case ZNE.MessageType.DOWNLOADDATA:
                      //!
                      this.ProcessDownloadDataMessage( m_Message ); break
 
               //!* Web data message advisory.
               case ZNE.MessageType.WEBDATA:
                      //!
                      this.ProcessWebDataMessage( m_Message ); break;
 
 
 
             }//!switch
 
 
      }//!While
 
 
 
     //!* 5). End  reading messages.
     _Server.MessageMngr.EndReadMessage();
 
 
}//!Method 
 
 
 
 
Surprised What! reading messages while there is available data to read, it will make some hickups to the game and block game
logic for some time within the while(  _Server.MessageMngr.MessageIsAvailable()  ), because overtime I'm
expecting data to arrive. Nah, that is not the expecting case, that's why there's a begin read message -
"_Server.MessageMngr.BeginReadMessage()" declaration before reading all available data, It will only read
data that has been qued up since the last call from BeginReadMessage and all other messages that has been
left or currrently just arriving(which is happening in the background) will be read to the next game update
cycle, hickups and procedure blocking only comes along, if you'll  be receiving thousands of message per
frame or game update which is irrational and it won't happen on a normal multiplayer games Wink.
 
 
 
So, What's inside  the message? image below shows the members of message class where I can cast the
package DATA base on message type.
 
MESSAGE
 
// E.g. The simplest message type is TEXTDATA, the DATA object is actually just a string type, as shown below:
 
/// _____________________________________________________________
/// <summary>
/// TEXT DATA  MESSAGE  PROCESSING
/// </summary>
public void ProcessTextDataMessage(  ZNC.Message message )
{
 
    //!* It's safe from here to cast the message DATA as string, since the message data type is already been knowned as TEXTDATA.
    //!
    string  m_TextMessage  =  ( string )message.DATA
 
 
    if(        message.Command == 10  )  // Say, 10 is my user-defined game command for my chat box message board.
    {
           _ChatMessageBoard.InsertMessage( message.SenderName,  m_TextMessage );
    }
    else if( message.Command == 11  )  // Say, 11 is my user-defined game command as a private message sent to me.
    {        
---------------------------------------------------------------------------------------------------------------------------------------------|
 
 
 
Well, I guess my next  post should be the following Nerd :
 
* Dealing with network system MessageType.SYSDATA, how to read ZNC.SystemData from message and what action should be taken.
 
* What is meta data  MessageType.METADATA,  sending meta data using   ZNC.MetaDataWriiter and readng  ZNC.MetaData from received mesage.
* What is text data    MessageType.TEXTDATA,   sending text data using    ZNC.TextDataWriter   and reading Text data from received message.
* What is raw bytes   MessageType.BYTESDATA, sending raw bytes using   ZNC.BytesDataWriter and reading Raw bytes data from received message.
* What is object data MessageType.OBJDATA,     sending object data using ZNC.ObjDataWriter     and reading  Object data from received message.
* What is file data     MessageType.FILEDATA,    sending file data using      ZNC.FileDataWriter    and reading ZNC.FileData from received message.
 
* How to download file fom web and reading  ZNC.DownloadData advisory from received message.
* How to send web request        and reading  ZNC.WebData advisory from received message.
 
 
 
02 settembre

Auto discovery

 
My last post disscuss how Z-Communicator can start listening to clients, connecting to server, but how can a client knows,
that a particular machine created a game session or started a server for other machine station to join in, ok, this topic covers
multiplayer games on LAN or local subnet only.
 
Whether using UDP or TCP protocol type,  my implemenation are capable of announcing a game session or server accross
the local subnet, the caster manager will take care on how the game session can be announce accross the local subnet. 
 
The caster type below is using ZNE.CasterType.Multicast  broadcasting mechanism than pure ZNE.CasterType.Broadcast
mechanism, Broadcast type is I believed already been deprecated and not supported in IPv6, ZNE.CasterType.Multicast on
the other hand  works fine on both IPv4 and IPv6 protocol version implementation.
 
 
 
// Using  ZNC = ZGDK.Net.Core;
// Using  ZNE  = ZGDK.Net.Enum;
// Using  ZNH  = ZGDK.Net.Helper;
 
 
//!>> 1). Creating lobby server new instance.
//
ZNC.LobbyServer _Server = new ZNC.LobbyServer();
 
  
//!>>  2). Preparing server network configuration
//
ZNC.ServerConfig m_ServerConfig = new ZNC.ServerConfig();  m_ServerConfig.SetDefault();
//  
m_ServerConfig.Connection          = ZNE.ConnectionType.LAN;
m_ServerConfig.IPVersion            = ZNE.IPVersion.IPv4;
m_ServerConfig.Protocol              = ZNE.Protocol.TCP;
m_ServerConfig.SocketType         = ZNE.SocketType.Berkely; 
m_ServerConfig.IPAddress           = ZNH.GetMachineLocalIP();  
m_ServerConfig.ServerPort          = 60055;
//
m_ServerConfig.CasterPort           = 60057;
m_ServerConfig.CasterType          = ZNE.CasterType.Multicast;
m_ServerConfig.CasterGroup        = ZNE.CasterGroup.IPv4_WORKGROUP;
//
m_ServerConfig.AcceptorMode      = ZNE.SAcceptorMode.Thread;
m_ServerConfig.ReceiverMode      = ZNE.SReceiverMode.TcpThreadPoll;
m_ServerConfig.SenderMode        = ZNE.SenderMode.Asynchronous;
//
m_ServerConfig.ApplicationName  = "Mech Rider-Z Alpha Rel. 0.002";
m_ServerConfig.LobbyName         = "Dexter Channel";
 
 

//!>>  3). Start lobby server service with custom network configuration.
//
_Server.StartLobbyService( m_ServerConfig );
 
 
//!>>  4). Start accepting client connection.
//
_Server.AcceptorMngr.StartAccepting();
 
 
//!>>  5). Start caster manager service and start announcing the game every 300Ms.
//
_Server.CasterMngr.StartCasterService();
//
_Server.CasterMngr.StartAnnouncingGame( 300 );
 
 
Lobby server caster manager:
CasterMngr
 
 
Well, that's it, the server caster manager already been started and the game announce the server availability accross
the local subnet for clients to join in or connect and login to server, the following code shows how the client can
automatically discover the announcing server/s.
 
//!>>> Client end, searching for local game/s E.g.  "Mech Rider-Z Alpha Rel. 0.002" for 1Sec or 1000ms.
//
ZNC.LocalGames[] m_LocalGames = ZNH.SearchLocalGames(  "Mech Rider-Z Alpha Rel. 0.002",  1000  );
 
 
Local games members:
LocalGames
 
Once a client find local game/s, yes game/s, it can search all available same game tittle creating game
session or running as a server within the local area network,  it can retrieve every game server information
such as computer name, server port,  lobby description and it's local IP address to connect to.
 
 
NOTE: Blog contents may be slightly modified from time to time to comply with library's latest revision for future referencing.
01 settembre

Stop listening!

 
From my previous post, I already tackled how the server can be configure and to start it services, when the lobby server started it service, it doesnt mean it can already accept incomming  client connection, I need to to call first _Server.AcceptorMngr.StartAccepting() to start the acceptor manager for listening to any new incomming client connecting to server.
 
Some will argue, that once the server service started, it should start accepting client connection immediately. So, why I still need to call _Server.AcceptorMngr.StartAccepting() manually to be able to start accepting client connection,  the reason is, in my implementation it is capable to Start and Stop listening for new incomming client connection anytime I wish,  I can call _Server.AcceptorMngr.StartAccepting()  and _Server.AcceptorMngr.StopAccepting() anytime anywhere within the scope namespace, once the server service started.
 
For instance, if Im going to create a multiplayer RTS game with maximum of 8 players playing on local area network, once all 8 players already been filled and joined the game and the session started, it doesnt make sense that the server still need to listen for new connection, since the game was designed for maximum of 8 players only, once the game started I can call _Server.AcceptorMngr.StopAccepting() without loosing connection to already connected clients and at the end of the game session, back to game creation menu I can start calling again _Server.AcceptorMngr.StartAccepting()  Coz other player may wish to leave the game session and for other players to join for the new game session, and yes, running a lobby server type over th internet is a different story.
 
 
Here's the code from the previous post, just adding on how to start listening for a new incomming client connection:
 
 
// Using  ZNC = ZGDK.Net.Core;
// Using  ZNE  = ZGDK.Net.Enum;
// Using  ZNH  = ZGDK.Net.Helper;
 

 //!>> 1). Creating lobby server new instance.
 //
 ZNC.LobbyServer _Server = new ZNC.LobbyServer();
  
//!>>  2). Preparing server network configuration
//
ZNC.ServerConfig m_ServerConfig = new ZNC.ServerConfig();  m_ServerConfig.SetDefault();
//  
m_ServerConfig.Connection          = ZNE.ConnectionType.LAN;
m_ServerConfig.IPVersion            = ZNE.IPVersion.IPv4;
m_ServerConfig.Protocol              = ZNE.Protocol.UDP;
m_ServerConfig.SocketType         = ZNE.SocketType.Berkely; 
m_ServerConfig.IPAddress           = ZNH.GetMachineLocalIP();  
m_ServerConfig.ServerPort          = 60055;
//
m_ServerConfig.CasterPort           = 60057;
m_ServerConfig.CasterType          = ZNE.CasterType.Multicast;
m_ServerConfig.CasterGroup        = ZNE.CasterGroup.IPv4_WORKGROUP;
//
m_ServerConfig.AcceptorMode      = ZNE.SAcceptorMode.Thread;
m_ServerConfig.ReceiverMode      = ZNE.SReceiverMode.UdpThreadReceiver;
m_ServerConfig.SenderMode        = ZNE.SenderMode.Asynchronous;
//
m_ServerConfig.ApplicationName  = "Mech Rider-Z Alpha Rel. 0.002";
m_ServerConfig.LobbyName         = "Dexter Channel";
 

//!>>  3). Start lobby server service with custom network configuration.
//
 _Server.StartLobbyService( m_ServerConfig );
 
//!>>  4). Start accepting client connection.
//
 _Server.AcceptorMngr.StartAccepting();
 
 
 
Lobby server acceptor manager:
AcceptorMngr
 
 
I already discuss how to start and configure the lobby server service, and now how to start and stop listening for client connection, my next post will be on how the clients can automatically detect created game session or server within the local subnet and what kind of access I can grant to connecting client.
 
 Wink Hmmm, this blog of mine starting to look a tutorial on how to use Z-Communicator, than a work and process development blog.
 
NOTE: Blog contents may be slightly modified from time to time to comply with library's latest revision for future referencing.
24 luglio

Lobby server overview

 
 
 
Finally, the draft for Z-Communicator Lobby server class members are already been in place,
the following class diagram exposed the list of  members from LobbyServer class type.
 
 
LobbyServer
 
 
 
Complete lobby server class overview :
 
ServerClass  
Click me to see the actual and larger image.
 
 
 
 NOTE: Blog contents may be slightly modified from time to time to comply with library's latest revision for future referencing.
01 luglio

Socket parallel processing illusion

 
 
 
While I'm currently blogging on this, I'm also watching the official trailer of  Diablo 3 and at the same time chatting to some of my friends on-line, Oh yeh, and theres a lot of other application currently open at my desktop, including visual studio where I'm currently working on my communicator project. Wow! so this is what they call multitasking on windows, running multiple applications at the same time Tongue out
 
Nah, I dont think all of those things are running at the same time. My perception is that the OS just slices up the processor's time to process each task, giving each and every active program application to run in it's own slice time for a given period, say per second and since I'm currently using a computer station that does not have a multi-core processor, basically the computer is just doing it's tasks so fast, repeatedly, giving an illusion that everything is happening simultaneously.
 
So, How's all the above babbling related to networking? the thing is a .NET program can also be consider like a virtual machine, in the sense that it can handle multiple tasks and gets some slice of processor's time, Coz "usually we dont want to performs socket processing operation to block our main application logic for running contineously". The .NET Frameworks gave us the ability to do multi-threading for our application, whether it's a dedicated thread or an asynchronous events using it's CLR thread pool.

If your using .NET technology on windows platform, well, your in luck, whether  you are using a dual core/ tri core or quad core processors, you don't have to do a thing or tweak anything in the code, the OS will managed all the threading stuff to work on different cores automagically.

Apparently from my previous post, the SenderMode does not have an option for dedicated thread, while both AcceptorMode and ReceiverMode has the ability to do it's processing on a dedicated thread. Normally, the application has a full control when sending data, unlike listening for incomming connection or waiting for data to arrive, we cannot exactly tell when the data will arrive, So basically, as much as possible we really need to monitor all incomming connection or data at all time, we dont want to miss a single incomming packet, dont we?
 
So, what is the best method for socket processing? again, in my implementation, it really depends on the nature of the application objectives or game type, the following diagram for socket processing scheme are just some of the variety that can be implemented by just changing the socket core's enumerated processing mode for Listening, Receiving and  Sending data.
 
 
 
 

26 giugno

Interchangeable network technology

 
I know, it's a daunting task to design, develop and implement a robust managed network library,  can be totally mind boggling and may cause loss of hair Wink, but when you really need something specific to suits your different application needs or if you think you can do better implementation than using the tools that are already available,  most of the time you force yourself to code from scratch or at least you try to roll your own implementation.

Of course, I know the notion of  'reinventing the wheel' and I'm also aware that there are lots of great network library project already been created out there and ready to use, but most of them I've seen so far, only offers a single network implementation or using only a specific .NET network technology features and you feel like your still working on the socket level. This is one of the main reason I wanted to try and create my own network library to find out which network technology and socket processing scheme will be best suited to different types of multiuser application needs. What I really wanted to do is to develop a network library which is interchangeable with ease of use and to be able to test other networking technology and different kinds of socket processing scheme in the simplest form.

A configurable network computing implementation seems to be a good idea to start designing a network library, and here's my implementation on how I configure my server that uses different kinds of enumerated network technology and socket processing scheme. The port  is the only one that needs to be set manually, other implementations are all enumerated to lessen the hardcoding hassle, whether I wanted to use IPv4 or IPv6, UDP or TCP, .NetClients or  raw Socket Berkely, IPv4-Broadcasting or IPv4/IPv6-Multicasting and other network settings. The most interesting part I've done so far, I can choose what type of socket processing scheme for a specific application requirements or game type by selecting socket cores processing mode to work Synchronously, Asynchronously,  Per player thread, Per player asynchronous mode or a single thread for socket selecting or polling mode.
 
Before starting listening for connecting clients, first I need to set  my network setting  parameter  when creating  new lobby server instance and sets my server configuration parameter when starting lobby service, that's it and I'm ready to start listening to any incomming client connection.
 

// Using  ZNC = ZGDK.Net.Core;
// Using  ZNE  = ZGDK.Net.Enum;
// Using  ZNH  = ZGDK.Net.Helper;
 

//!>>> 1). Creating lobby server network settings.
//
ZNC.SNetSetting m_NetSetting = new ZNC.SNetSetting(); m_NetSetting.SetDefault();
//
//!>> Frequencies
m_NetSetting.Frequencies.SendingFrequency     =  200; // ms latency
m_NetSetting.Frequencies.ResendFrequency      =  400;        
m_NetSetting.Frequencies.KeepAliveFrequency   = 3000;        
//
//!>> MpTU   Maximum payload Transmission Unit
m_NetSetting..MpTU.Small      =   1400; //Bytes = (  7 KBps-for- 56kbps-iSpeed           ) / ( 1000ms / 200ms-latency )
m_NetSetting..MpTU.Medium  =   2800; //Bytes = ( 14 KBps-for-128kbps-iSpeed           ) / ( 1000ms / 200ms-latency )
m_NetSetting..MpTU.Larger     =  5600; //Bytes = (  28 KBps-for-256kbps-iSpeed and above ) / ( 1000ms / 200ms-latency )
//
//!>> Intervals
m_NetSetting.Intervals.SelectPollReadWait            = 32;
m_NetSetting.Intervals.SyncronouseSendTimeOut  = 5000;
m_NetSetting.Intervals.MaxPlayerIdleTime            = 15000;
m_NetSetting.Intervals.PlayerRemovalCountDown  = 4000;
//
//!>> Initial table capacity
m_NetSetting.Thresholds.MaxNumberOfGames   = 1;         
m_NetSetting.Thresholds.ReceivedQueTblSize     = 16;
m_NetSetting.Thresholds.MessageQueTblSize     = 32;
m_NetSetting.Thresholds.SendQueTblSize           = 64;
//
//!>> Max fails alert before disconnecting client
m_NetSetting.FailsAlerts.MaxPlayerResendFailsCount   = 16;           
m_NetSetting.FailsAlerts.MaxPlayerSendFailsCount      = 12;
m_NetSetting.FailsAlerts.MaxPlayerReceiveFailsCount  = 24;
m_NetSetting.FailsAlerts.MaxPlayerGarbageFailsCount = 32;
//!
//!>> Logger Debugger
m_NetSetting.LoggerConsole.Enable                          = true;
m_NetSetting.LoggerConsole.EchoEnable                   = true;
m_NetSetting.LoggerConsole.ShowReceivePacketInfo = false;
m_NetSetting.LoggerConsole.ShowSendPacketInfo     = false;
m_NetSetting.LoggerConsole.ShowPlayerTrafficFlow  = false;
 
//!>>> 2). Creating new server instance with prefered network settings.
//
ZNC.LobbyServer _Server = new ZNC.LobbyServer( m_NetSetting );
 
 

//!>> > 3)Preparing server configuration
//
ZNC.ServerConfig m_ServerConfig = new ZNC.ServerConfig();  m_ServerConfig.SetDefault();
// 
m_ServerConfig.ApplicationName  = "Mech Rider-Z Alpha Rel. 0.002";
m_ServerConfig.LobbyName         = "Dexter Channel";
//
m_ServerConfig.EnableIPv6          = false;
m_ServerConfig.Connection          = ZNE.ConnectionType.Internet;
m_ServerConfig.Protocol              = ZNE.Protocol.UDP;
m_ServerConfig.SocketType         = ZNE.SocketType.Berkely; 
m_ServerConfig.IPAddress           = ZNH.GetMachineLocalIP(  ZNE.IPVerion.IPv4  );  
m_ServerConfig.ServerPort          = 60055;
//
m_ServerConfig.CasterPort           = 60057;
m_ServerConfig.CasterType          = ZNE.CasterType.Multicast;
m_ServerConfig.CasterGroup        = ZNE.CasterGroup.IPv4_WORKGROUP;
//
m_ServerConfig.AcceptorMode      = ZNE.SAcceptorMode.UsingUDP;
m_ServerConfig.ReceiverMode      = ZNE.SReceiverMode.UdpThreadOnly;
m_ServerConfig.SenderMode        = ZNE.SenderMode.AsyncIOCP;

//!>>> 4). Start lobby server service with  prefered server configuration.
//
 _Server.StartLobbyService( m_ServerConfig );



//!>>> 5)Start accepting new client connection.
//
_Server.AcceptorMngr.StartAccepting();
 


"The following are just a brief descriptions of what particular network technology and processing scheme included in my implementation, and there are hundreds to thousands of complete information and in-details that can be found on the internet in each subject. "



S E R V E R   C O N F I G U R A T I O N :  

Application Name

m_ServerConfig.ApplicationName  = "Mech Rider-Z Alpha Rel. 0.002";

Why I need to specify the name of the application in server configuration? though, this is irrelevant when using connection type over the internet, but working on local area network the client needs to specify the game or application name when searching for available games accross the local subnet.
 
ZNC.LocalGames[] m_LocalGames = ZNH.SearchLocalGames(  "Mech Rider-Z Alpha Rel. 0.002",  1000  );
 
The client should retrieves all available machine's hosting "Mech Rider-Z Alpha Rel. 0.002" game as an example on the local sub-net.  I will ellaborate more on this later on when I tackle my implementation for Boadcasting and Multicasting messages accross the local sub-net and how game sessions can be automatically discover.
 
 
Lobby name

 m_ServerConfig.LobbyName = "Dexter Channel";
 
Whether hosting a game over the internet or on the local sub-net, assigning a lobby name is one way to identify the host machine, for instance multiple machine created a game session, the client looking for available games, should retrieve all created game sessions along with lobby name for host distinction, though, from using over the internet I intend to use Lobby name as a Server channel description hosting the same game over the internet using different server machine.
 
 
Internet Protocol Version
 
I may say  socket  works  through  a  network layers like the Internet Protocol (IP), IP is the main core that  provides to transport data in various network environment such as local area  network (LAN) and  wide  area network (WAN) particularly the internet. The two well known network layers  Internet  Protocol  version  are IPv4 and IPv6. I will not tackle here what ever happened to the IPv5, but the next generation Internet Protocol is IPv6 and it's the latest version  of the Internet  Protocol. I'm  supporting  both IPv4 and IPv6 on my network library, I believe it's a good decision to add a support to IPv6 rather than to deal with it later on, the functionality of my network library works on both Internet Protocol version 4 and 6.
 
m_ServerConfig.EnableIPv6 = false;   //  Using IPv4 only


Network connection type

The more, the merrier! playing games on LAN is definitely cool and imagine how much fun it would be to play the same game you are playing on LAN that can also be played by others over the internet. Though, connection type should only be configured on the client end, the server end in my implementation also need to know what connection type you are intend to use for internal setting.

 
m_ServerConfig.Connection = ZNE.ConnectionType.Internet;  
                                                                          LAN
 
 
Network Protocol
 
The two well known Network Protocol in  computer networking are  Transport Connection Protocol (TCP) and the Unrealiable Datagram Protocol... Oppps! my bad, the correct one is User Datagram Protocol (UDP). TCP and UPD are the dominant protocols lurking over the internet and to most networking environments. TCP and UDP should be supported in my implementation, although  some  may say that if you can implement a robust reliable UDP messaging scheme there's no need for a TCP implementation, because it will just overkill the design, but never the less I'm still supporting the use of TCP protocol. The .NET framework Remoting features in my design plan will be drop due to my own implementation on sending and updating of on object remotely.
 
m_ServerConfig.Protocol = ZNE.Protocol.UDP;  
                                                            TCP
 
 
Socket type
 
The .NET framework offers UdpClient, TcpClient, TcpListener and Raw Socket Berkely for it's socket interface, but which one is better and more effecient? well, the best thing to do is to run the the application and choose which socket type works best for your application. Luckily, both socket interface are supported in my implementation.

m_ServerConfig.SocketType = ZNE.SocketType.Berkely
                                                                     NetClient
 
 
IP Address
 
Exchanging messages needs to agree with the same protocol, whether you are using a TCP or UDP, each message has to contain the address of its destination just like a telegrams. Shame on me, if I still need to manually hardcoded the machine's local IP address everytime I transfer and use different station to run the server application, creating a simple method that returns machine's local IP address is very handy.
 
m_ServerConfig.IPAddress  = ZNH.GetMachineLocalIP(  ZNE.IPVerion.IPv4 );  

 
Listener port
 
How many ports should I need to open on the server end? In my implementation whenever the announcer is enable which will only works on the local subnet but not over the internet, a new UDP socket and port will be open and created whether the core socket is using TCP or UDP protocol.  The core socket using UDP or TCP,  a  single server listener port is only needed.

m_ServerConfig.ListernerPort  = 60055;


Broadcasting and Multicasting
 
The option for sending messages to all other machines across the local sub-net or group of host at the same time should not be taken for granted, implementing broadcasting or multicasting features are also included in my implementation, which can surely save a lot of bandwidht, more details on this when I discuss about the role of  caster manager and it's  functionality in my implementation. The following are the options to configure broadcast messaging.

m_ServerConfig.CasterPort    = 60057;
 
m_ServerConfig.CasterType   = ZNE.CasterType.Multicast;  
                                                                      Broadcast;
 
m_ServerConfig.CasterGroup = ZNE.CasterGroup.IPv4_WORKGROUP;
       
Here's the complete enumeration for caster group address :
 
BROADCAST,
IPv4_WORKGROUP,IPv4_ROUTER, IPv4_OSPF, IPv4_OSPF_ROUTER, IPv4_RIPV2, IPv4_EIGRP, IPv4_VRRP,IPv4_IGMP,
IPv6_WORKGROUPSEGMENT, IPv6_WORKGROUPSITE, IPv6_ROUTER, IPv6_DHCP, IPv6_NIS


 
Socket processing scheme
  
Socket processing scheme is the most important aspect in network implementation IMO. I will tackle this part on my next post including some diagram for each processing scheme that can that can be acquire by just changing the socket core processing mode.
 
m_ServerConfig.AcceptorMode  = ZNE.SAcceptorMode.Thread;  
                                                                                 Asynchronous;
                                                                                 UsingUDP;                                                                              

m_ServerConfig.ReceiverMode   = ZNE.SReceiverMode.TcpThreadPollOnly;
                                                                                 TcpThreadPollIOCP

                                                                                 TcpThreadSelectOnly
                                                                                 TcpThreadSelectIOCP

                                                                                 TcpThreadPerPlayer
                                                                                 TcpRecusrsiveAsyncIOCPPerPlayer

                                                                                 UdpThreadOnly
                                                                                 UdpThreadIOCP
                                                                                 UdpRecursiveAsyncIOCP
 
 
m_ServerConfig.SenderMode     = ZNE.SenderMode.Synchronous
                                                                              Asynchronous;
 



LOBBY SERVER NETWORK SETTING:

...

Basically, this is just the tip of the iceberg from the whole network implementation and  I can't wait to discuss the full functionality on the server end like the ff server managers :  _Server.AcceptorMngr,  _Server.SenderMngr,  _Server.ReceiverMngr,  _Server.MessageMngr,  _Server.CasterMngr, _Server.LobbyMngr, _Server.GameMngr, _Server.SessionMngr, Frequency tuning,  Error handling and Buffer overrun monitoring. 
 
NOTE: Blog contents may be slightly  modified from time to time to comply with library's latest revision and for future referencing.

10 giugno

PROLEGOMENON



.NET NETWORKING

The .NET Framework is invading the world of software development and it's coming 
and spreading very fast,  Waging it's high performance development tools and armed
with loads of support  and  goodies  and it's  now reaching most of developers today,
and for those who is not seeing it coming, well, the decision is yours.
 
What's  really  my  area  of  interest  from  the  .NET  frameworks  are  it's network
programming  features (aside from XNA),  it  has  helped me a lot to solved many of
my  networking  problems (socket)  by  using  C#  and  it's  socket  functionality
particularly the Berkely raw Socket, UdpClient, TcpClient and TcpListener.

Since the .NET Framework  Socket classes are built on top of  Winsock 2.0, there's
no  need  or  reason  for  me  to find a non managed or a third party native network
library and try to work on it. The high performance socket API of the .NET Framework
can handle most of  sending and receiving task for handling data accross the wire
whether it's a LAN base or over the internet, and theres a new added features to the
Socket class in the .NET Framework  (.Net 3.5/Orcas ) which enables much greater
throuhput than previous versions with it's new programming API.



PROJECT OBJECTIVES

The  aim  of  this  project is to create a socket peers communication network library 
that can be applicable  both for  transaction  application and at the same time served 
as a network engine for games,  handling  data  messages  through socket peers only
without  using  ODBC/OLEDB/ADO/ADO.NET  and  not directly connected to any heavy
weight databases.

Once the data is fetch and arrives to host or at the endpoint thats the time I will  save
the  data  locally  to  any  type  of  storage  I  wanted  to  use,  whether  save  it  to a
databases  such as  mySQL,  MS SQL  Server  or  just  save  it  to  a  flat  file  such
XML, ACCESS and of course to my favorite  DBF/MDX file,  which I think is much
more secure and fast  than let the user directly connect to the database itself remotely.
Although, I  know  this  approach  is  not  suited for other  kinds  of transaction base
application,  but  for  anything  lite and  where performance  is needed like games for

instance, I believe working directly with sockets will do the job right.

"Since I'm  still heavily working and researching for this project, I don't guarantee that
everything I  will  mentioned  and jotted  down to this blog is technically accurate and
correct, what I have here is based on my research, interpreteration and understanding
to the socket networking subject and should not be consider as facts or best approach."

 

NOTE: Blog contents may be modified from time to time to comply with library's latest revision and for future referencing.