Сетевое программирование в .NET. Расшифровка IP-адреса (IP address specification). Обеспечение надежности доставки пакетов, страница 36

The RequestConnect method handles initiating the connection. Notice that the server IP parameter is by reference; this is because it is possible to pass the method a host name (rather than an IP address), but the IP will be resolved and the actual string will be changed to the IP address. This allows the host application to take advantage of the hostname resolution, and is required when using other functions within Genesis (as many of the connection search functions will only accept the remote host IP address). The other parameter to note is the last parameter, which is an out parameter and returns the connection request ID. This ID is a number unique to all connection requests and allows a connection request to be cancelled via the CancelConnect method.

Note that establishing a connection is an asynchronous operation, and to catch whether a connection has succeeded requires the use of two events, OnConnectionRequestTimedOut and OnConnectionStateChanged. If the connection attempt times out, the former event is fired. If the connection attempt succeeds, then the latter is fired with arguments that show a connection has been established. Both of these events allow access to the remote host address and the connection request ID generated at the call to RequestConnect to allow differentiation between different connections and connection requests. This can be seen implemented in the GenesisChatClient project.

Sending Data to Remote Hosts

Genesis wraps this functionality in very easy to use method. Two of the methods reside in the IConnection object, these are shown below:

int SendUnreliableCommand(byte flags, string opcode, string[] fields);

int SendReliableCommand(byte flags, string opcode, string[] fields);

These two methods allow sending a single command packet to the remote host associated with the IConnection object. The opcode and fields can be any data the host application recognizes, valid values for the flags are given below (from Constants.cs):

//Command packet flags

public static byte FLAGS_NONE = 0;

public static byte FLAGS_CONNECTIONLESS = 1;

public static byte FLAGS_ENCRYPTED = 2;

public static byte FLAGS_COMPOUNDPIECE = 4;

public static byte FLAGS_COMPOUNDEND = 8;

public static byte FLAGS_RELIABLE = 16;

public static byte FLAGS_SEQUENCED = 32;

Of the flags available in the Constants.cs file, only one should ever be used manually in the method calls, and that is FLAGS_SEQUENCED which applies a sequencing to unreliable packets. The other flags are automatically set by Genesis and should not be changed by the host application.

It is possible to broadcast a command packet to multiple remote hosts using the following methods in the IGenesisUDP interface:

int SendUnreliableCommandToAll(BroadcastFilter filter,

byte flags, string opcode, string[] fields);

int SendReliableCommandToAll(BroadcastFilter filter,

byte flags, string opcode, string[] fields);

These methods work exactly the same as the first two, except they take broadcast filter flags, which are defined in Constants.cs as:

[Flags]

public enum BroadcastFilter : int

{

None     = 0,  //Filter out everything

Servers  = 1,  //Send to servers we are connected to.

Clients  = 2,  //Send to clients connected to us.

All      = Servers | Clients,

//Send to both servers

//and clients (every connection).

AuthedOnly = 4,//Only send to authed clients or servers we are authed with.

}

This allows the broadcast to be limited to servers, clients, and optionally only those connections that have successfully been authenticated.

Points of Interest

It is important to note that the events in Genesis are thrown on a separate thread - not the UI thread. This means that the Invoke method is needed to pass the event to the UI thread, if changing UI elements is your goal. The chat server uses this technique to change the UI based on event data.

When the StopListen method is called, Genesis automatically sends out a disconnection packet to all of the remote hosts connected to it to inform them that it is shutting down.

The only method within Genesis that can take a hostname instead of an IP is RequestConnect. All other methods need an explicit IP address.