123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- /**
- @page Tutorial Tutorial
- @ref Initialization
- @ref CreateServer
- @ref CreateClient
- @ref ManageHost
- @ref SendingPacket
- @ref Disconnecting
- @ref Connecting
- @section Initialization Initialization
- You should include the file <enet/enet.h> when using ENet. Do not
- include <enet.h> without the directory prefix, as this may cause
- file name conflicts on some systems.
- Before using ENet, you must call enet_initialize() to initialize the
- library. Upon program exit, you should call enet_deinitialize() so
- that the library may clean up any used resources.
- @code
- #include <enet/enet.h>
- int
- main (int argc, char ** argv)
- {
- if (enet_initialize () != 0)
- {
- fprintf (stderr, "An error occurred while initializing ENet.\n");
- return EXIT_FAILURE;
- }
- atexit (enet_deinitialize);
- ...
- ...
- ...
- }
- @endcode
-
- @section CreateServer Creating an ENet server
- Servers in ENet are constructed with enet_host_create(). You must
- specify an address on which to receive data and new connections, as
- well as the maximum allowable numbers of connected peers. You may
- optionally specify the incoming and outgoing bandwidth of the server
- in bytes per second so that ENet may try to statically manage
- bandwidth resources among connected peers in addition to its dynamic
- throttling algorithm; specifying 0 for these two options will cause
- ENet to rely entirely upon its dynamic throttling algorithm to manage
- bandwidth.
- When done with a host, the host may be destroyed with
- enet_host_destroy(). All connected peers to the host will be reset,
- and the resources used by the host will be freed.
- @code
- ENetAddress address;
- ENetHost * server;
- /* Bind the server to the default localhost. */
- /* A specific host address can be specified by */
- /* enet_address_set_host (& address, "x.x.x.x"); */
- address.host = ENET_HOST_ANY;
- /* Bind the server to port 1234. */
- address.port = 1234;
- server = enet_host_create (& address /* the address to bind the server host to */,
- 32 /* allow up to 32 clients and/or outgoing connections */,
- 2 /* allow up to 2 channels to be used, 0 and 1 */,
- 0 /* assume any amount of incoming bandwidth */,
- 0 /* assume any amount of outgoing bandwidth */);
- if (server == NULL)
- {
- fprintf (stderr,
- "An error occurred while trying to create an ENet server host.\n");
- exit (EXIT_FAILURE);
- }
- ...
- ...
- ...
- enet_host_destroy(server);
- @endcode
- @section CreateClient Creating an ENet client
- Clients in ENet are similarly constructed with enet_host_create() when
- no address is specified to bind the host to. Bandwidth may be
- specified for the client host as in the above example. The peer count
- controls the maximum number of connections to other server hosts that
- may be simultaneously open.
- @code
- ENetHost * client;
- client = enet_host_create (NULL /* create a client host */,
- 1 /* only allow 1 outgoing connection */,
- 2 /* allow up 2 channels to be used, 0 and 1 */,
- 57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */,
- 14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */);
- if (client == NULL)
- {
- fprintf (stderr,
- "An error occurred while trying to create an ENet client host.\n");
- exit (EXIT_FAILURE);
- }
- ...
- ...
- ...
- enet_host_destroy(client);
- @endcode
- @section ManageHost Managing an ENet host
- ENet uses a polled event model to notify the programmer of significant
- events. ENet hosts are polled for events with enet_host_service(),
- where an optional timeout value in milliseconds may be specified to
- control how long ENet will poll; if a timeout of 0 is specified,
- enet_host_service() will return immediately if there are no events to
- dispatch. enet_host_service() will return 1 if an event was dispatched
- within the specified timeout.
- Beware that most processing of the network with the ENet stack is done
- inside enet_host_service(). Both hosts that make up the sides of a connection
- must regularly call this function to ensure packets are actually sent and
- received. A common symptom of not actively calling enet_host_service()
- on both ends is that one side receives events while the other does not.
- The best way to schedule this activity to ensure adequate service is, for
- example, to call enet_host_service() with a 0 timeout (meaning non-blocking)
- at the beginning of every frame in a game loop.
- Currently there are only four types of significant events in ENet:
- An event of type ENET_EVENT_TYPE_NONE is returned if no event occurred
- within the specified time limit. enet_host_service() will return 0
- with this event.
- An event of type ENET_EVENT_TYPE_CONNECT is returned when either a new client
- host has connected to the server host or when an attempt to establish a
- connection with a foreign host has succeeded. Only the "peer" field of the
- event structure is valid for this event and contains the newly connected peer.
- An event of type ENET_EVENT_TYPE_RECEIVE is returned when a packet is received
- from a connected peer. The "peer" field contains the peer the packet was
- received from, "channelID" is the channel on which the packet was sent, and
- "packet" is the packet that was sent. The packet contained in the "packet"
- field must be destroyed with enet_packet_destroy() when you are done
- inspecting its contents.
- An event of type ENET_EVENT_TYPE_DISCONNECT is returned when a connected peer
- has either explicitly disconnected or timed out. Only the "peer" field of the
- event structure is valid for this event and contains the peer that
- disconnected. Only the "data" field of the peer is still valid on a
- disconnect event and must be explicitly reset.
- @code
- ENetEvent event;
-
- /* Wait up to 1000 milliseconds for an event. */
- while (enet_host_service (client, & event, 1000) > 0)
- {
- switch (event.type)
- {
- case ENET_EVENT_TYPE_CONNECT:
- printf ("A new client connected from %x:%u.\n",
- event.peer -> address.host,
- event.peer -> address.port);
- /* Store any relevant client information here. */
- event.peer -> data = "Client information";
- break;
- case ENET_EVENT_TYPE_RECEIVE:
- printf ("A packet of length %u containing %s was received from %s on channel %u.\n",
- event.packet -> dataLength,
- event.packet -> data,
- event.peer -> data,
- event.channelID);
- /* Clean up the packet now that we're done using it. */
- enet_packet_destroy (event.packet);
-
- break;
-
- case ENET_EVENT_TYPE_DISCONNECT:
- printf ("%s disconnected.\n", event.peer -> data);
- /* Reset the peer's client information. */
- event.peer -> data = NULL;
- }
- }
- ...
- ...
- ...
- @endcode
- @section SendingPacket Sending a packet to an ENet peer
- Packets in ENet are created with enet_packet_create(), where the size
- of the packet must be specified. Optionally, initial data may be
- specified to copy into the packet.
- Certain flags may also be supplied to enet_packet_create() to control
- various packet features:
- ENET_PACKET_FLAG_RELIABLE specifies that the packet must use reliable
- delivery. A reliable packet is guaranteed to be delivered, and a
- number of retry attempts will be made until an acknowledgement is
- received from the foreign host the packet is sent to. If a certain
- number of retry attempts is reached without any acknowledgement, ENet
- will assume the peer has disconnected and forcefully reset the
- connection. If this flag is not specified, the packet is assumed an
- unreliable packet, and no retry attempts will be made nor
- acknowledgements generated.
- A packet may be resized (extended or truncated) with
- enet_packet_resize().
- A packet is sent to a foreign host with
- enet_peer_send(). enet_peer_send() accepts a channel id over which to
- send the packet to a given peer. Once the packet is handed over to
- ENet with enet_peer_send(), ENet will handle its deallocation and
- enet_packet_destroy() should not be used upon it.
- One may also use enet_host_broadcast() to send a packet to all
- connected peers on a given host over a specified channel id, as with
- enet_peer_send().
- Queued packets will be sent on a call to enet_host_service().
- Alternatively, enet_host_flush() will send out queued packets without
- dispatching any events.
- @code
- /* Create a reliable packet of size 7 containing "packet\0" */
- ENetPacket * packet = enet_packet_create ("packet",
- strlen ("packet") + 1,
- ENET_PACKET_FLAG_RELIABLE);
- /* Extend the packet so and append the string "foo", so it now */
- /* contains "packetfoo\0" */
- enet_packet_resize (packet, strlen ("packetfoo") + 1);
- strcpy (& packet -> data [strlen ("packet")], "foo");
-
- /* Send the packet to the peer over channel id 0. */
- /* One could also broadcast the packet by */
- /* enet_host_broadcast (host, 0, packet); */
- enet_peer_send (peer, 0, packet);
- ...
- ...
- ...
- /* One could just use enet_host_service() instead. */
- enet_host_flush (host);
- @endcode
- @section Disconnecting Disconnecting an ENet peer
- Peers may be gently disconnected with enet_peer_disconnect(). A
- disconnect request will be sent to the foreign host, and ENet will
- wait for an acknowledgement from the foreign host before finally
- disconnecting. An event of type ENET_EVENT_TYPE_DISCONNECT will be
- generated once the disconnection succeeds. Normally timeouts apply to
- the disconnect acknowledgement, and so if no acknowledgement is
- received after a length of time the peer will be forcefully
- disconnected.
- enet_peer_reset() will forcefully disconnect a peer. The foreign host
- will get no notification of a disconnect and will time out on the
- foreign host. No event is generated.
- @code
- ENetEvent event;
-
- enet_peer_disconnect (peer, 0);
- /* Allow up to 3 seconds for the disconnect to succeed
- * and drop any packets received packets.
- */
- while (enet_host_service (client, & event, 3000) > 0)
- {
- switch (event.type)
- {
- case ENET_EVENT_TYPE_RECEIVE:
- enet_packet_destroy (event.packet);
- break;
- case ENET_EVENT_TYPE_DISCONNECT:
- puts ("Disconnection succeeded.");
- return;
- ...
- ...
- ...
- }
- }
-
- /* We've arrived here, so the disconnect attempt didn't */
- /* succeed yet. Force the connection down. */
- enet_peer_reset (peer);
- ...
- ...
- ...
- @endcode
- @section Connecting Connecting to an ENet host
- A connection to a foreign host is initiated with enet_host_connect().
- It accepts the address of a foreign host to connect to, and the number
- of channels that should be allocated for communication. If N channels
- are allocated for use, their channel ids will be numbered 0 through
- N-1. A peer representing the connection attempt is returned, or NULL
- if there were no available peers over which to initiate the
- connection. When the connection attempt succeeds, an event of type
- ENET_EVENT_TYPE_CONNECT will be generated. If the connection attempt
- times out or otherwise fails, an event of type
- ENET_EVENT_TYPE_DISCONNECT will be generated.
- @code
- ENetAddress address;
- ENetEvent event;
- ENetPeer *peer;
- /* Connect to some.server.net:1234. */
- enet_address_set_host (& address, "some.server.net");
- address.port = 1234;
- /* Initiate the connection, allocating the two channels 0 and 1. */
- peer = enet_host_connect (client, & address, 2, 0);
-
- if (peer == NULL)
- {
- fprintf (stderr,
- "No available peers for initiating an ENet connection.\n");
- exit (EXIT_FAILURE);
- }
-
- /* Wait up to 5 seconds for the connection attempt to succeed. */
- if (enet_host_service (client, & event, 5000) > 0 &&
- event.type == ENET_EVENT_TYPE_CONNECT)
- {
- puts ("Connection to some.server.net:1234 succeeded.");
- ...
- ...
- ...
- }
- else
- {
- /* Either the 5 seconds are up or a disconnect event was */
- /* received. Reset the peer in the event the 5 seconds */
- /* had run out without any significant event. */
- enet_peer_reset (peer);
- puts ("Connection to some.server.net:1234 failed.");
- }
- ...
- ...
- ...
- @endcode
- */
|