diff --git a/design.txt b/design.txt deleted file mode 100644 index 9a88dba..0000000 --- a/design.txt +++ /dev/null @@ -1,117 +0,0 @@ -* Why ENet? - - ENet evolved specifically as a UDP networking layer for the multiplayer -first person shooter Cube. Cube necessitated low latency communcation with -data sent out very frequently, so TCP was an unsuitable choice due to its -high latency and stream orientation. UDP, however, lacks many sometimes -necessary features from TCP such as reliability, sequencing, unrestricted -packet sizes, and connection management. So UDP by itself was not suitable -as a network protocol either. No suitable freely available networking -libraries existed at the time of ENet's creation to fill this niche. - - UDP and TCP could have been used together in Cube to benefit somewhat -from both of their features, however, the resulting combinations of protocols -still leaves much to be desired. TCP lacks multiple streams of communication -without resorting to opening many sockets and complicates delineation of -packets due to its buffering behavior. UDP lacks sequencing, connection -management, management of bandwidth resources, and imposes limitations on -the size of packets. A significant investment is required to integrate these -two protocols, and the end result is worse off in features and performance -than the uniform protocol presented by ENet. - - ENet thus attempts to address these issues and provide a single, uniform -protocol layered over UDP to the developer with the best features of UDP and -TCP as well as some useful features neither provide, with a much cleaner -integration than any resulting from a mixture of UDP and TCP. - -* Connection management - - ENet provides a simple connection interface over which to communicate -with a foreign host. The liveness of the connection is actively monitored -by pinging the foreign host at frequent intervals, and also monitors the -network conditions from the local host to the foreign host such as the -mean round trip time and packet loss in this fashion. - -* Sequencing - - Rather than a single byte stream that complicates the delineation -of packets, ENet presents connections as multiple, properly sequenced packet -streams that simplify the transfer of various types of data. - - ENet provides sequencing for all packets by assigning to each sent -packet a sequence number that is incremented as packets are sent. ENet -guarentees that no packet with a higher sequence number will be delivered -before a packet with a lower sequence number, thus ensuring packets are -delivered exactly in the order they are sent. - - For unreliable packets, ENet will simply discard the lower sequence -number packet if a packet with a higher sequence number has already been -delivered. This allows the packets to be dispatched immediately as they -arrive, and reduce latency of unreliable packets to an absolute minimum. -For reliable packets, if a higher sequence number packet arrives, but the -preceding packets in the sequence have not yet arrived, ENet will stall -delivery of the higher sequence number packets until its predecessors -have arrived. - -* Channels - - Since ENet will stall delivery of reliable packets to ensure proper -sequencing, and consequently any packets of higher sequence number whether -reliable or unreliable, in the event the reliable packet's predecessors -have not yet arrived, this can introduce latency into the delivery of other -packets which may not need to be as strictly ordered with respect to the -packet that stalled their delivery. - - To combat this latency and reduce the ordering restrictions on packets, -ENet provides multiple channels of communication over a given connection. -Each channel is independently sequenced, and so the delivery status of -a packet in one channel will not stall the delivery of other packets -in another channel. - -* Reliability - - ENet provides optional reliability of packet delivery by ensuring the -foreign host acknowledges receipt of all reliable packets. ENet will attempt -to resend the packet up to a reasonable amount of times, if no acknowledgement -of the packet's receipt happens within a specified timeout. Retry timeouts -are progressive and become more lenient with every failed attempt to allow -for temporary turbulence in network conditions. - -* Fragmentation and reassembly - - ENet will send and deliver packets regardless of size. Large packets are -fragmented into many smaller packets of suitable size, and reassembled on -the foreign host to recover the original packet for delivery. The process -is entirely transparent to the developer. - -* Aggregation - - ENet aggregates all protocol commands, including acknowledgements and -packet transfer, into larger protocol packets to ensure the proper utilization -of the connection and to limit the opportunities for packet loss that might -otherwise result in further delivery latency. - -* Adaptability - - ENet provides an in-flight data window for reliable packets to ensure -connections are not overwhelmed by volumes of packets. It also provides a -static bandwidth allocation mechanism to ensure the total volume of packets -sent and received to a host don't exceed the host's capabilities. Further, -ENet also provides a dynamic throttle that responds to deviations from normal -network connections to rectify various types of network congestion by further -limiting the volume of packets sent. - -* Portability - - ENet works on Windows and any other Unix or Unix-like platform providing -a BSD sockets interface. The library has a small and stable code base that -can easily be extended to support other platforms and integrates easily. - -* Freedom - - ENet demands no royalties and doesn't carry a viral license that would -restrict you in how you might use it in your programs. ENet is licensed under -a short-and-sweet MIT-style license, which gives you the freedom to do anything -you want with it (well, almost anything). - - diff --git a/tutorial.txt b/tutorial.txt deleted file mode 100644 index 9341d6c..0000000 --- a/tutorial.txt +++ /dev/null @@ -1,325 +0,0 @@ -* Using ENet - - 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. - -i.e. - -int -main (int argc, char ** argv) -{ - if (enet_initialize () != 0) - { - fprintf (stderror, "An error occurred while initializing ENet.\n"); - return EXIT_FAILURE; - } - atexit (enet_deinitialize); - ... - ... - ... -} - -* 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. - -i.e. - - 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 */, - 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); - -* 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. - -i.e. - - ENetHost * client; - - clienet = enet_host_create (NULL /* create a client host */, - 1 /* only allow 1 outgoing connection */, - 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); - -* 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. - - 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. - -i.e. - - 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 disconected.\n", event.peer -> data); - - /* Reset the peer's client information. */ - - event.peer -> data = NULL; - } - } - ... - ... - ... - -* 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 guarenteed 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. - -i.e. - - /* 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 3. - * One could also broadcast the packet by - * enet_host_broadcast (host, 3, packet); - */ - enet_peer_send (peer, 3, packet); - ... - ... - ... - /* One could just use enet_host_service() instead. */ - enet_host_flush (host); - -* 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. - -i.e. - ENetEvent event; - - enet_peer_disconnect (& client -> peers [0], 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 (& client -> peers [0]); - ... - ... - ... - -* Connecting to an ENet host - - A connection to a foregin 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. - -i.e. - 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); - - 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."); - } - ... - ... - ... -