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