Development back on the trunk!
[crack-attack.git] / enet / tutorial.txt
blobf187e2d41eb66d8b4b69cd99fd1dba209091b1a4
1 * Using ENet
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.
7 i.e.
9 int 
10 main (int argc, char ** argv) 
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     ...
22         
23 * Creating an ENet server
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.
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.
38 i.e.
40     ENetAddress address;
41     ENetHost * server;
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;
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);
66 * Creating an ENet client
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.
73 i.e.
75     ENetHost * client;
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 */);
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);
93 * Managing an ENet host
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.
102     Currently there are only four types of significant events in ENet:
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.
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.
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.
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.
126 i.e.
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);
140             /* Store any relevant client information here. */
141             event.peer -> data = "Client information";
143             break;
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);
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);
160             /* Reset the peer's client information. */
162             event.peer -> data = NULL;
163         }
164     }
165     ...
166     ...
167     ...
169 * Sending a packet to an ENet peer            
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.
175     Certain flags may also be supplied to enet_packet_create() to control 
176 various packet features:
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.
187     A packet may be resized (extended or truncated) with enet_packet_resize().
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.
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().
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.
201 i.e.
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);
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);
225 * Disconnecting an ENet peer
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.
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.
239 i.e.
240     ENetEvent event;
241     
242     enet_peer_disconnect (& client -> peers [0]);
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;
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     ...
272 * Connecting to an ENet host
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.
284 i.e.
285     ENetAddress address;
286     ENetEvent event;
287     ENetPeer *peer;
289     /* Connect to some.server.net:1234. */
290     enet_address_set_host (& address, "some.server.net");
291     address.port = 1234;
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);
320         puts ("Connection to some.server.net:1234 failed.");
321     }
322     ...
323     ...
324     ...