home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2007 September / maximum-cd-2007-09.iso / Assets / data / AssaultCube_v0.93.exe / source / enet / tutorial.txt < prev    next >
Encoding:
Text File  |  2006-11-06  |  11.6 KB  |  326 lines

  1. * Using ENet
  2.  
  3.     Before using ENet, you must call enet_initialize() to initialize the
  4. library. Upon program exit, you should call enet_deinitialize() so that
  5. the library may clean up any used resources.
  6.  
  7. i.e.
  8.  
  9. int 
  10. main (int argc, char ** argv) 
  11. {
  12.     if (enet_initialize () != 0)
  13.     {
  14.         fprintf (stderror, "An error occurred while initializing ENet.\n");
  15.         return EXIT_FAILURE;
  16.     }
  17.     atexit (enet_deinitialize);
  18.     ...
  19.     ...
  20.     ...
  21. }
  22.         
  23. * Creating an ENet server
  24.  
  25.     Servers in ENet are constructed with enet_host_create(). You must specify
  26. an address on which to receive data and new connections, as well as the maximum
  27. allowable numbers of connected peers. You may optionally specify the incoming
  28. and outgoing bandwidth of the server in bytes per second so that ENet may try
  29. to statically manage bandwidth resources among connected peers in addition to
  30. its dynamic throttling algorithm; specifying 0 for these two options will cause 
  31. ENet to rely entirely upon its dynamic throttling algorithm to manage 
  32. bandwidth.
  33.  
  34.     When done with a host, the host may be destroyed with enet_host_destroy().
  35. All connected peers to the host will be reset, and the resources used by
  36. the host will be freed.
  37.  
  38. i.e.
  39.  
  40.     ENetAddress address;
  41.     ENetHost * server;
  42.  
  43.     /* Bind the server to the default localhost.
  44.      * A specific host address can be specified by
  45.      * enet_address_set_host (& address, "x.x.x.x");
  46.      */
  47.     address.host = ENET_HOST_ANY;
  48.     /* Bind the server to port 1234. */
  49.     address.port = 1234;
  50.  
  51.     server = enet_host_create (& address /* the address to bind the server host to */, 
  52.                 32 /* allow up to 32 clients and/or outgoing connections */,
  53.                 0 /* assume any amount of incoming bandwidth */,
  54.                 0 /* assume any amount of outgoing bandwidth */);
  55.     if (server == NULL)
  56.     {
  57.         fprintf (stderr, 
  58.                  "An error occurred while trying to create an ENet server host.\n");
  59.         exit (EXIT_FAILURE);
  60.     }
  61.     ...
  62.     ...
  63.     ...
  64.     enet_host_destroy(server);
  65.  
  66. * Creating an ENet client
  67.  
  68.     Clients in ENet are similarly constructed with enet_host_create() when no
  69. address is specified to bind the host to. Bandwidth may be specified for the 
  70. client host as in the above example. The peer count controls the maximum number
  71. of connections to other server hosts that may be simultaneously open.
  72.  
  73. i.e.
  74.  
  75.     ENetHost * client;
  76.  
  77.     clienet = enet_host_create (NULL /* create a client host */,
  78.                 1 /* only allow 1 outgoing connection */,
  79.                 57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */,
  80.                 14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */);
  81.  
  82.     if (client == NULL)
  83.     {
  84.         fprintf (stderr, 
  85.                  "An error occurred while trying to create an ENet client host.\n");
  86.         exit (EXIT_FAILURE);
  87.     }
  88.     ...
  89.     ...
  90.     ...
  91.     enet_host_destroy(client);
  92.  
  93. * Managing an ENet host
  94.  
  95.     ENet uses a polled event model to notify the programmer of significant 
  96. events. ENet hosts are polled for events with enet_host_service(), where an
  97. optional timeout value in milliseconds may be specified to control how long
  98. ENet will poll; if a timeout of 0 is specified, enet_host_service() will
  99. return immediately if there are no events to dispatch. enet_host_service()
  100. will return 1 if an event was dispatched within the specified timeout.
  101.  
  102.     Currently there are only four types of significant events in ENet:
  103.  
  104. An event of type ENET_EVENT_TYPE_NONE is returned if no event occurred
  105. within the specified time limit. enet_host_service() will return 0
  106. with this event.
  107.  
  108. An event of type ENET_EVENT_TYPE_CONNECT is returned when either a new client
  109. host has connected to the server host or when an attempt to establish a 
  110. connection with a foreign host has succeeded. Only the "peer" field of the 
  111. event structure is valid for this event and contains the newly connected peer.
  112.  
  113. An event of type ENET_EVENT_TYPE_RECEIVE is returned when a packet is received
  114. from a connected peer. The "peer" field contains the peer the packet was 
  115. received from, "channelID" is the channel on which the packet was sent, and 
  116. "packet" is the packet that was sent. The packet contained in the "packet" 
  117. field must be destroyed with enet_packet_destroy() when you are done 
  118. inspecting its contents.
  119.  
  120. An event of type ENET_EVENT_TYPE_DISCONNECT is returned when a connected peer
  121. has either explicitly disconnected or timed out. Only the "peer" field of the
  122. event structure is valid for this event and contains the peer that 
  123. disconnected. Only the "data" field of the peer is still valid on a 
  124. disconnect event and must be explicitly reset.
  125.  
  126. i.e.
  127.  
  128.     ENetEvent event;
  129.     
  130.     /* Wait up to 1000 milliseconds for an event. */
  131.     while (enet_host_service (client, & event, 1000) > 0)
  132.     {
  133.         switch (event.type)
  134.         {
  135.         case ENET_EVENT_TYPE_CONNECT:
  136.             printf ("A new client connected from %x:%u.\n", 
  137.                     event.peer -> address.host,
  138.                     event.peer -> address.port);
  139.  
  140.             /* Store any relevant client information here. */
  141.             event.peer -> data = "Client information";
  142.  
  143.             break;
  144.  
  145.         case ENET_EVENT_TYPE_RECEIVE:
  146.             printf ("A packet of length %u containing %s was received from %s on channel %u.\n",
  147.                     event.packet -> dataLength,
  148.                     event.packet -> data,
  149.                     event.peer -> data,
  150.                     event.channelID);
  151.  
  152.             /* Clean up the packet now that we're done using it. */
  153.             enet_packet_destroy (event.packet);
  154.             
  155.             break;
  156.            
  157.         case ENET_EVENT_TYPE_DISCONNECT:
  158.             printf ("%s disconected.\n", event.peer -> data);
  159.  
  160.             /* Reset the peer's client information. */
  161.  
  162.             event.peer -> data = NULL;
  163.         }
  164.     }
  165.     ...
  166.     ...
  167.     ...
  168.  
  169. * Sending a packet to an ENet peer            
  170.  
  171.     Packets in ENet are created with enet_packet_create(), where the size of
  172. the packet must be specified. Optionally, initial data may be specified to 
  173. copy into the packet.
  174.  
  175.     Certain flags may also be supplied to enet_packet_create() to control 
  176. various packet features:
  177.  
  178. ENET_PACKET_FLAG_RELIABLE specifies that the packet must use reliable delivery.
  179. A reliable packet is guarenteed to be delivered, and a number of retry attempts
  180. will be made until an acknowledgement is received from the foreign host the
  181. packet is sent to. If a certain number of retry attempts is reached without
  182. any acknowledgement, ENet will assume the peer has disconnected and forcefully
  183. reset the connection. If this flag is not specified, the packet is assumed
  184. an unreliable packet, and no retry attempts will be made nor acknowledgements
  185. generated.
  186.  
  187.     A packet may be resized (extended or truncated) with enet_packet_resize().
  188.  
  189.     A packet is sent to a foreign host with enet_peer_send(). enet_peer_send()
  190. accepts a channel id over which to send the packet to a given peer. Once the
  191. packet is handed over to ENet with enet_peer_send(), ENet will handle its
  192. deallocation and enet_packet_destroy() should not be used upon it.
  193.  
  194.     One may also use enet_host_broadcast() to send a packet to all connected
  195. peers on a given host over a specified channel id, as with enet_peer_send().
  196.  
  197.     Queued packets will be sent on a call to enet_host_service().
  198. Alternatively, enet_host_flush() will send out queued packets without
  199. dispatching any events.
  200.  
  201. i.e.
  202.  
  203.     /* Create a reliable packet of size 7 containing "packet\0" */
  204.     ENetPacket * packet = enet_packet_create ("packet", 
  205.                                               strlen ("packet") + 1, 
  206.                                               ENET_PACKET_FLAG_RELIABLE);
  207.  
  208.     /* Extend the packet so and append the string "foo", so it now
  209.      * contains "packetfoo\0"
  210.      *
  211.     enet_packet_resize (packet, strlen ("packetfoo") + 1);
  212.     strcpy (& packet -> data [strlen ("packet")], "foo");
  213.     
  214.     /* Send the packet to the peer over channel id 3.
  215.      * One could also broadcast the packet by
  216.      * enet_host_broadcast (host, 3, packet);
  217.      */
  218.     enet_peer_send (peer, 3, packet);
  219.     ...
  220.     ...
  221.     ...
  222.     /* One could just use enet_host_service() instead. */
  223.     enet_host_flush (host);
  224.  
  225. * Disconnecting an ENet peer
  226.  
  227.     Peers may be gently disconnected with enet_peer_disconnect(). A disconnect
  228. request will be sent to the foreign host, and ENet will wait for an 
  229. acknowledgement from the foreign host before finally disconnecting. An
  230. event of type ENET_EVENT_TYPE_DISCONNECT will be generated once the
  231. disconnection succeeds. Normally timeouts apply to the disconnect
  232. acknowledgement, and so if no acknowledgement is received after a length
  233. of time the peer will be forcefully disconnected.
  234.  
  235.     enet_peer_reset() will forcefully disconnect a peer. The foreign host
  236. will get no notification of a disconnect and will time out on the foreign
  237. host. No event is generated.
  238.  
  239. i.e.
  240.     ENetEvent event;
  241.     
  242.     enet_peer_disconnect (& client -> peers [0]);
  243.  
  244.     /* Allow up to 3 seconds for the disconnect to succeed
  245.      * and drop any packets received packets.
  246.      */
  247.     while (enet_host_service (client, & event, 3000) > 0)
  248.     {
  249.         switch (event.type)
  250.         {
  251.         case ENET_EVENT_TYPE_RECEIVE:
  252.             enet_packet_destroy (event.packet);
  253.             break;
  254.  
  255.         case ENET_EVENT_TYPE_DISCONNECT:
  256.             puts ("Disconnection succeeded.");
  257.             return;
  258.         ...
  259.         ...
  260.         ...
  261.         }
  262.     }
  263.     
  264.     /* We've arrived here, so the disconnect attempt didn't succeed yet.
  265.      * Force the connection down.
  266.      */
  267.     enet_peer_reset (& client -> peers [0]);
  268.     ...
  269.     ...
  270.     ...
  271.  
  272. * Connecting to an ENet host
  273.  
  274.     A connection to a foregin host is initiated with enet_host_connect().
  275. It accepts the address of a foreign host to connect to, and the number of
  276. channels that should be allocated for communication. If N channels are
  277. allocated for use, their channel ids will be numbered 0 through N-1.
  278. A peer representing the connection attempt is returned, or NULL if there
  279. were no available peers over which to initiate the connection. When the 
  280. connection attempt succeeds, an event of type ENET_EVENT_TYPE_CONNECT will 
  281. be generated. If the connection attempt times out or otherwise fails, an
  282. event of type ENET_EVENT_TYPE_DISCONNECT will be generated.
  283.  
  284. i.e.
  285.     ENetAddress address;
  286.     ENetEvent event;
  287.     ENetPeer *peer;
  288.  
  289.     /* Connect to some.server.net:1234. */
  290.     enet_address_set_host (& address, "some.server.net");
  291.     address.port = 1234;
  292.  
  293.     /* Initiate the connection, allocating the two channels 0 and 1. */
  294.     peer = enet_host_connect (client, & address, 2);    
  295.     
  296.     if (peer == NULL)
  297.     {
  298.        fprintf (stderr, 
  299.                 "No available peers for initiating an ENet connection.\n");
  300.        exit (EXIT_FAILURE);
  301.     }
  302.     
  303.     /* Wait up to 5 seconds for the connection attempt to succeed.
  304.     if (enet_host_service (client, & event, 5000) > 0 &&
  305.         event.type == ENET_EVENT_TYPE_CONNECT)
  306.     {
  307.         puts ("Connection to some.server.net:1234 succeeded.");
  308.         ...
  309.         ...
  310.         ...
  311.     }
  312.     else
  313.     {
  314.         /* Either the 5 seconds are up or a disconnect event was
  315.          * received. Reset the peer in the event the 5 seconds
  316.          * had run out without any significant event.
  317.          */
  318.         enet_peer_reset (peer);
  319.  
  320.         puts ("Connection to some.server.net:1234 failed.");
  321.     }
  322.     ...
  323.     ...
  324.     ...
  325.  
  326.