[enet-cvs] CVS: enet host.c,1.2,1.3 peer.c,1.2,1.3 protocol.c,1.2,1.3 unix.c,1.1,1.2 win32.c,1.2,1.3
ENet CVS
enet-discuss@lists.puremagic.com
Fri, 7 Jun 2002 20:29:14 -0600
Update of /home/enet/cvsroot/enet
In directory sferik:/tmp/cvs-serv1105
Modified Files:
host.c peer.c protocol.c unix.c win32.c
Log Message:
Added channels, revised throttle, fixed bugs, etc. etc.
Index: host.c
===================================================================
RCS file: /home/enet/cvsroot/enet/host.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- host.c 2002/02/10 22:24:41 1.2
+++ host.c 2002/06/08 02:29:12 1.3
@@ -2,14 +2,14 @@
#include <enet/enet.h>
ENetHost *
-enet_host_create (const ENetAddress * address, size_t peerCount)
+enet_host_create (const ENetAddress * address, size_t peerCount, uint32 incomingBandwidth, uint32 outgoingBandwidth)
{
ENetHost * host = (ENetHost *) enet_malloc (sizeof (ENetHost));
ENetPeer * currentPeer;
host -> peers = (ENetPeer *) enet_calloc (peerCount, sizeof (ENetPeer));
- host -> socket = enet_socket_create (address);
+ host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, address);
if (host -> socket == ENET_SOCKET_NULL)
{
enet_free (host -> peers);
@@ -21,6 +21,10 @@
if (address != NULL)
host -> address = * address;
+ host -> incomingBandwidth = incomingBandwidth;
+ host -> outgoingBandwidth = outgoingBandwidth;
+ host -> bandwidthThrottleEpoch = 0;
+ host -> recalculateBandwidthLimits = 0;
host -> peerCount = peerCount;
host -> lastServicedPeer = host -> peers;
host -> commandCount = 0;
@@ -33,14 +37,15 @@
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
+ currentPeer -> host = host;
currentPeer -> incomingPeerID = currentPeer - host -> peers;
currentPeer -> data = NULL;
+ enet_list_clear (& currentPeer -> acknowledgements);
enet_list_clear (& currentPeer -> sentReliableCommands);
+ enet_list_clear (& currentPeer -> sentUnreliableCommands);
enet_list_clear (& currentPeer -> outgoingReliableCommands);
enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
- enet_list_clear (& currentPeer -> incomingReliableCommands);
- enet_list_clear (& currentPeer -> incomingUnreliableCommands);
enet_peer_reset (currentPeer);
}
@@ -67,11 +72,18 @@
}
ENetPeer *
-enet_host_connect (ENetHost * host, const ENetAddress * address)
+enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount)
{
ENetPeer * currentPeer;
- ENetOutgoingCommand * outgoingCommand;
+ ENetChannel * channel;
+ ENetProtocol command;
+ if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
+ channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
+ else
+ if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
+ channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
+
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
@@ -84,35 +96,41 @@
return NULL;
currentPeer -> state = ENET_PEER_STATE_CONNECTING;
- currentPeer -> challenge = (uint32) rand ();
currentPeer -> address = * address;
-
- outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
+ currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
+ currentPeer -> channelCount = channelCount;
- currentPeer -> outgoingReliableSequenceNumber = 1;
+ for (channel = currentPeer -> channels;
+ channel < & currentPeer -> channels [channelCount];
+ ++ channel)
+ {
+ channel -> outgoingReliableSequenceNumber = 0;
+ channel -> outgoingUnreliableSequenceNumber = 0;
+ channel -> incomingReliableSequenceNumber = 0;
+ channel -> incomingUnreliableSequenceNumber = 0;
- outgoingCommand -> reliableSequenceNumber = 1;
- outgoingCommand -> unreliableSequenceNumber = 0;
- outgoingCommand -> sentTime = 0;
- outgoingCommand -> roundTripTimeout = 0;
- outgoingCommand -> roundTripTimeoutLimit = 0;
- outgoingCommand -> packet = NULL;
-
- outgoingCommand -> command.header.command = ENET_PROTOCOL_COMMAND_CONNECT;
- outgoingCommand -> command.header.flags = 0;
- outgoingCommand -> command.header.commandLength = sizeof (ENetProtocolConnect);
- outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_32 (1);
- outgoingCommand -> command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
- outgoingCommand -> command.connect.packetSize = ENET_HOST_TO_NET_16 (currentPeer -> packetSize);
- outgoingCommand -> command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
+ enet_list_clear (& channel -> incomingReliableCommands);
+ enet_list_clear (& channel -> incomingUnreliableCommands);
+ }
+
+ command.header.command = ENET_PROTOCOL_COMMAND_CONNECT;
+ command.header.channelID = 0xFF;
+ command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
+ command.header.commandLength = sizeof (ENetProtocolConnect);
+ command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
+ command.connect.packetSize = ENET_HOST_TO_NET_16 (currentPeer -> packetSize);
+ command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
+ command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
+ command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
+ command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
- enet_list_insert (enet_list_end (& currentPeer -> outgoingReliableCommands), outgoingCommand);
+ enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
return currentPeer;
}
void
-enet_host_broadcast (ENetHost * host, ENetPacket * packet)
+enet_host_broadcast (ENetHost * host, uint8 channelID, ENetPacket * packet)
{
ENetPeer * currentPeer;
@@ -123,10 +141,176 @@
if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
continue;
- enet_peer_send (currentPeer, packet);
+ enet_peer_send (currentPeer, channelID, packet);
}
if (packet -> referenceCount == 0)
enet_packet_destroy (packet);
}
+void
+enet_host_bandwidth_limit (ENetHost * host, uint32 incomingBandwidth, uint32 outgoingBandwidth)
+{
+ host -> incomingBandwidth = incomingBandwidth;
+ host -> outgoingBandwidth = outgoingBandwidth;
+ host -> recalculateBandwidthLimits = 1;
+}
+
+void
+enet_host_bandwidth_throttle (ENetHost * host)
+{
+ uint32 timeCurrent = enet_time_get (),
+ elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
+ peersTotal = 0,
+ dataTotal = 0,
+ peersRemaining,
+ bandwidth,
+ throttle,
+ bandwidthLimit;
+ int needsAdjustment;
+ ENetPeer * peer;
+ ENetProtocol command;
+
+ if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_EPOCH)
+ return;
+
+ for (peer = host -> peers;
+ peer < & host -> peers [host -> peerCount];
+ ++ peer)
+ {
+ if (peer -> state != ENET_PEER_STATE_CONNECTED)
+ continue;
+
+ ++ peersTotal;
+ dataTotal += peer -> outgoingDataTotal;
+ }
+
+ if (peersTotal == 0)
+ return;
+
+ peersRemaining = peersTotal;
+ needsAdjustment = 1;
+
+ if (host -> outgoingBandwidth == 0)
+ bandwidth = ~0;
+ else
+ bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
+
+ while (peersRemaining > 0 && needsAdjustment != 0)
+ {
+ needsAdjustment = 0;
+
+ if (dataTotal < bandwidth)
+ throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
+ else
+ throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
+
+ for (peer = host -> peers;
+ peer < & host -> peers [host -> peerCount];
+ ++ peer)
+ {
+ uint32 peerBandwidth;
+
+ if (peer -> state != ENET_PEER_STATE_CONNECTED ||
+ peer -> incomingBandwidth == 0 ||
+ peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
+ continue;
+
+ peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
+ if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
+ continue;
+
+ peer -> packetThrottleLimit = (peerBandwidth *
+ ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
+
+ if (peer -> packetThrottleLimit == 0)
+ peer -> packetThrottleLimit = 1;
+
+ peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
+
+
+ needsAdjustment = 1;
+ -- peersRemaining;
+ bandwidth -= peerBandwidth;
+ dataTotal -= peerBandwidth;
+ }
+ }
+
+ if (peersRemaining > 0)
+ for (peer = host -> peers;
+ peer < & host -> peers [host -> peerCount];
+ ++ peer)
+ {
+ if (peer -> state != ENET_PEER_STATE_CONNECTED ||
+ peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
+ continue;
+
+ peer -> packetThrottleLimit = throttle;
+ }
+
+ if (host -> incomingBandwidth > 0 &&
+ host -> recalculateBandwidthLimits)
+ {
+ host -> recalculateBandwidthLimits = 0;
+
+ peersRemaining = peersTotal;
+ bandwidth = host -> incomingBandwidth;
+ needsAdjustment = 1;
+
+ while (peersRemaining > 0 && needsAdjustment != 0)
+ {
+ needsAdjustment = 0;
+ bandwidthLimit = bandwidth / peersRemaining;
+
+ for (peer = host -> peers;
+ peer < & host -> peers [host -> peerCount];
+ ++ peer)
+ {
+ if (peer -> state != ENET_PEER_STATE_CONNECTED ||
+ peer -> incomingBandwidthThrottleEpoch == timeCurrent)
+ continue;
+
+ if (bandwidthLimit <= peer -> outgoingBandwidth)
+ continue;
+
+ peer -> incomingBandwidthThrottleEpoch = timeCurrent;
+
+ needsAdjustment = 1;
+ -- peersRemaining;
+ bandwidth -= peer -> outgoingBandwidth;
+ }
+ }
+
+ for (peer = host -> peers;
+ peer < & host -> peers [host -> peerCount];
+ ++ peer)
+ {
+ if (peer -> state != ENET_PEER_STATE_CONNECTED)
+ continue;
+
+ command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT;
+ command.header.channelID = 0xFF;
+ command.header.flags = 0;
+ command.header.commandLength = sizeof (ENetProtocolBandwidthLimit);
+ command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
+
+ if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
+ command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
+ else
+ command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
+
+ enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+ }
+ }
+
+ host -> bandwidthThrottleEpoch = timeCurrent;
+
+ for (peer = host -> peers;
+ peer < & host -> peers [host -> peerCount];
+ ++ peer)
+ {
+ peer -> incomingDataTotal = 0;
+ peer -> outgoingDataTotal = 0;
+ }
+}
+
Index: peer.c
===================================================================
RCS file: /home/enet/cvsroot/enet/peer.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- peer.c 2002/02/10 22:24:41 1.2
+++ peer.c 2002/06/08 02:29:12 1.3
@@ -2,9 +2,37 @@
#include <enet/enet.h>
int
-enet_peer_send (ENetPeer * peer, ENetPacket * packet)
+enet_peer_throttle (ENetPeer * peer, uint32 statistic, uint32 mean, uint32 variance)
{
- ENetOutgoingCommand * outgoingCommand;
+ if (mean > variance &&
+ statistic < mean - variance)
+ {
+ peer -> packetThrottle += ENET_PEER_PACKET_THROTTLE_ACCELERATION;
+
+ if (peer -> packetThrottle > peer -> packetThrottleLimit)
+ peer -> packetThrottle = peer -> packetThrottleLimit;
+
+ return 1;
+ }
+ else
+ if (statistic > mean + variance)
+ {
+ if (peer -> packetThrottle > ENET_PEER_PACKET_THROTTLE_DECELERATION)
+ peer -> packetThrottle -= ENET_PEER_PACKET_THROTTLE_DECELERATION;
+ else
+ peer -> packetThrottle = 0;
+
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+enet_peer_send (ENetPeer * peer, uint8 channelID, ENetPacket * packet)
+{
+ ENetChannel * channel = & peer -> channels [channelID];
+ ENetProtocol command;
size_t fragmentLength;
if (peer -> state != ENET_PEER_STATE_CONNECTED)
@@ -15,136 +43,95 @@
if (packet -> dataLength > fragmentLength)
{
uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
- startSequenceNumber = ENET_HOST_TO_NET_32 (peer -> outgoingReliableSequenceNumber + 1),
- fragmentNumber = 0,
- fragmentOffset = 0;
+ startSequenceNumber = ENET_HOST_TO_NET_32 (channel -> outgoingReliableSequenceNumber + 1),
+ fragmentNumber,
+ fragmentOffset;
packet -> flags |= ENET_PACKET_FLAG_RELIABLE;
- do
+ for (fragmentNumber = 0,
+ fragmentOffset = 0;
+ fragmentOffset < packet -> dataLength;
+ ++ fragmentNumber,
+ fragmentOffset += fragmentLength)
{
- outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
-
- ++ peer -> outgoingReliableSequenceNumber;
-
- outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber;
- outgoingCommand -> unreliableSequenceNumber = 0;
- outgoingCommand -> sentTime = 0;
- outgoingCommand -> roundTripTimeout = 0;
- outgoingCommand -> roundTripTimeoutLimit = 0;
- outgoingCommand -> fragmentOffset = fragmentOffset;
-
- if (packet -> dataLength - fragmentOffset >= fragmentLength)
- outgoingCommand -> fragmentLength = fragmentLength;
- else
- outgoingCommand -> fragmentLength = packet -> dataLength - fragmentOffset;
-
- outgoingCommand -> command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT;
- outgoingCommand -> command.header.flags = 0;
- outgoingCommand -> command.header.commandLength = sizeof (ENetProtocolSendFragment);
- outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_32 (peer -> outgoingReliableSequenceNumber);
- outgoingCommand -> command.sendFragment.startSequenceNumber = startSequenceNumber;
- outgoingCommand -> command.sendFragment.fragmentCount = fragmentCount;
- outgoingCommand -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
- outgoingCommand -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
- outgoingCommand -> command.sendFragment.fragmentOffset = ENET_HOST_TO_NET_32 (fragmentOffset);
-
- ++ packet -> referenceCount;
+ command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT;
+ command.header.channelID = channelID;
+ command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
+ command.header.commandLength = sizeof (ENetProtocolSendFragment);
+ command.sendFragment.startSequenceNumber = startSequenceNumber;
+ command.sendFragment.fragmentCount = fragmentCount;
+ command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
+ command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
+ command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);
- outgoingCommand -> packet = packet;
+ if (packet -> dataLength - fragmentOffset < fragmentLength)
+ fragmentLength = packet -> dataLength - fragmentOffset;
- ++ fragmentNumber;
- fragmentOffset += outgoingCommand -> fragmentLength;
+ enet_peer_queue_outgoing_command (peer, & command, packet, fragmentOffset, fragmentLength);
+ }
- enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
- } while (fragmentOffset < packet -> dataLength);
-
return 0;
}
-
- outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
- ++ packet -> referenceCount;
+ command.header.channelID = channelID;
if (packet -> flags & ENET_PACKET_FLAG_RELIABLE)
{
- ++ peer -> outgoingReliableSequenceNumber;
-
- outgoingCommand -> unreliableSequenceNumber = 0;
-
- outgoingCommand -> command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE;
- outgoingCommand -> command.header.commandLength = sizeof (ENetProtocolSendReliable);
-
- enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
+ command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE;
+ command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
+ command.header.commandLength = sizeof (ENetProtocolSendReliable);
}
else
{
- ++ peer -> outgoingUnreliableSequenceNumber;
-
- outgoingCommand -> unreliableSequenceNumber = peer -> outgoingUnreliableSequenceNumber;
-
- outgoingCommand -> command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
- outgoingCommand -> command.header.commandLength = sizeof (ENetProtocolSendUnreliable);
- outgoingCommand -> command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_32 (peer -> outgoingUnreliableSequenceNumber);
-
- enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
+ command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
+ command.header.flags = 0;
+ command.header.commandLength = sizeof (ENetProtocolSendUnreliable);
+ command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_32 (channel -> outgoingUnreliableSequenceNumber + 1);
}
-
- outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber;
- outgoingCommand -> sentTime = 0;
- outgoingCommand -> roundTripTimeout = 0;
- outgoingCommand -> roundTripTimeoutLimit = 0;
- outgoingCommand -> fragmentOffset = 0;
- outgoingCommand -> fragmentLength = packet -> dataLength;
- outgoingCommand -> packet = packet;
- outgoingCommand -> command.header.flags = 0;
- outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_32 (peer -> outgoingReliableSequenceNumber);
+ enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength);
return 0;
}
ENetPacket *
-enet_peer_receive (ENetPeer * peer)
+enet_peer_receive (ENetPeer * peer, uint8 channelID)
{
+ ENetChannel * channel = & peer -> channels [channelID];
ENetIncomingCommand * incomingCommand = NULL;
ENetPacket * packet;
- if (enet_list_empty (& peer -> incomingUnreliableCommands) == 0)
+ if (enet_list_empty (& channel -> incomingUnreliableCommands) == 0)
{
- incomingCommand = (ENetIncomingCommand *) enet_list_front (& peer -> incomingUnreliableCommands);
+ incomingCommand = (ENetIncomingCommand *) enet_list_front (& channel -> incomingUnreliableCommands);
- if (incomingCommand -> reliableSequenceNumber > peer -> incomingReliableSequenceNumber)
+ if (incomingCommand -> reliableSequenceNumber > channel -> incomingReliableSequenceNumber)
incomingCommand = NULL;
else
- peer -> incomingUnreliableSequenceNumber = incomingCommand -> unreliableSequenceNumber;
+ channel -> incomingUnreliableSequenceNumber = incomingCommand -> unreliableSequenceNumber;
}
if (incomingCommand == NULL &&
- enet_list_empty (& peer -> incomingReliableCommands) == 0)
+ enet_list_empty (& channel -> incomingReliableCommands) == 0)
{
do
{
- incomingCommand = (ENetIncomingCommand *) enet_list_front (& peer -> incomingReliableCommands);
+ incomingCommand = (ENetIncomingCommand *) enet_list_front (& channel -> incomingReliableCommands);
- if (incomingCommand -> acknowledged == 0 ||
- incomingCommand -> fragmentsRemaining > 0 ||
- incomingCommand -> reliableSequenceNumber > peer -> incomingReliableSequenceNumber + 1)
+ if (incomingCommand -> fragmentsRemaining > 0 ||
+ incomingCommand -> reliableSequenceNumber > channel -> incomingReliableSequenceNumber + 1)
return NULL;
- if (incomingCommand -> packet == NULL ||
- incomingCommand -> reliableSequenceNumber <= peer -> incomingReliableSequenceNumber)
+ if (incomingCommand -> reliableSequenceNumber <= channel -> incomingReliableSequenceNumber)
{
- if (incomingCommand -> reliableSequenceNumber == peer -> incomingReliableSequenceNumber + 1)
- peer -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber;
+ -- incomingCommand -> packet -> referenceCount;
+
+ if (incomingCommand -> packet -> referenceCount == 0)
+ enet_packet_destroy (incomingCommand -> packet);
- if (incomingCommand -> packet != NULL)
- {
- -- incomingCommand -> packet -> referenceCount;
-
- if (incomingCommand -> packet -> referenceCount == 0)
- enet_packet_destroy (incomingCommand -> packet);
- }
+ if (incomingCommand -> fragments != NULL)
+ enet_free (incomingCommand -> fragments);
enet_list_remove (& incomingCommand -> incomingCommandList);
@@ -153,12 +140,15 @@
incomingCommand = NULL;
}
} while (incomingCommand == NULL &&
- enet_list_empty (& peer -> incomingReliableCommands) == 0);
+ enet_list_empty (& channel -> incomingReliableCommands) == 0);
if (incomingCommand == NULL)
return NULL;
- peer -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber;
+ channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber;
+
+ if (incomingCommand -> fragmentCount > 0)
+ channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1;
}
if (incomingCommand == NULL)
@@ -178,13 +168,54 @@
return packet;
}
+static void
+enet_peer_reset_outgoing_commands (ENetList * queue)
+{
+ ENetOutgoingCommand * outgoingCommand;
+
+ while (enet_list_empty (queue) == 0)
+ {
+ outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue));
+
+ if (outgoingCommand -> packet != NULL)
+ {
+ -- outgoingCommand -> packet -> referenceCount;
+
+ if (outgoingCommand -> packet -> referenceCount == 0)
+ enet_packet_destroy (outgoingCommand -> packet);
+ }
+
+ enet_free (outgoingCommand);
+ }
+}
+
+static void
+enet_peer_reset_incoming_commands (ENetList * queue)
+{
+ ENetIncomingCommand * incomingCommand;
+
+ while (enet_list_empty (queue) == 0)
+ {
+ incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue));
+
+ if (incomingCommand -> packet != NULL)
+ {
+ -- incomingCommand -> packet -> referenceCount;
+
+ if (incomingCommand -> packet -> referenceCount == 0)
+ enet_packet_destroy (incomingCommand -> packet);
+ }
+
+ enet_free (incomingCommand);
+ }
+}
+
void
enet_peer_reset (ENetPeer * peer)
{
- ENetIncomingCommand * incomingCommand;
- ENetOutgoingCommand * outgoingCommand;
+ ENetChannel * channel;
- peer -> outgoingPeerID = ~0;
+ peer -> outgoingPeerID = 0xFFFF;
peer -> challenge = 0;
peer -> address.host = ENET_HOST_ANY;
@@ -192,6 +223,12 @@
peer -> state = ENET_PEER_STATE_DISCONNECTED;
+ peer -> incomingBandwidth = 0;
+ peer -> outgoingBandwidth = 0;
+ peer -> incomingBandwidthThrottleEpoch = 0;
+ peer -> outgoingBandwidthThrottleEpoch = 0;
+ peer -> incomingDataTotal = 0;
+ peer -> outgoingDataTotal = 0;
peer -> lastSendTime = 0;
peer -> lastReceiveTime = 0;
peer -> nextTimeout = 0;
@@ -201,150 +238,240 @@
peer -> packetLoss = 0;
peer -> packetLossVariance = 0;
peer -> packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE;
+ peer -> packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE;
+ peer -> packetThrottleCounter = 0;
+ peer -> packetThrottleEpoch = 0;
+ peer -> bestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
peer -> roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
peer -> roundTripTimeVariance = 0;
peer -> packetSize = ENET_PROTOCOL_MINIMUM_PACKET_SIZE;
- peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
peer -> reliableDataInTransit = 0;
- peer -> sentUnreliableSequenceNumber = 0;
peer -> outgoingReliableSequenceNumber = 0;
- peer -> outgoingUnreliableSequenceNumber = 0;
- peer -> incomingReliableSequenceNumber = 0;
- peer -> incomingUnreliableSequenceNumber = 0;
- while (enet_list_empty (& peer -> sentReliableCommands) == 0)
- {
- outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& peer -> sentReliableCommands));
+ peer -> windowSize = (peer -> host -> outgoingBandwidth /
+ ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
- if (outgoingCommand -> packet != NULL)
- {
- -- outgoingCommand -> packet -> referenceCount;
+ if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
+ peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+ else
+ if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
+ peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+
+ while (enet_list_empty (& peer -> acknowledgements) == 0)
+ enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements)));
+
+ enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
+ enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands);
+ enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands);
+ enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
- if (outgoingCommand -> packet -> referenceCount == 0)
- enet_packet_destroy (outgoingCommand -> packet);
- }
+ if (peer -> channels != NULL && peer -> channelCount > 0)
+ {
+ for (channel = peer -> channels;
+ channel < & peer -> channels [peer -> channelCount];
+ ++ channel)
+ {
+ channel -> outgoingReliableSequenceNumber = 0;
+ channel -> outgoingUnreliableSequenceNumber = 0;
+ channel -> incomingReliableSequenceNumber = 0;
+ channel -> incomingUnreliableSequenceNumber = 0;
+
+ enet_peer_reset_incoming_commands (& channel -> incomingReliableCommands);
+ enet_peer_reset_incoming_commands (& channel -> incomingUnreliableCommands);
+ }
- enet_free (outgoingCommand);
+ enet_free (peer -> channels);
}
- while (enet_list_empty (& peer -> outgoingReliableCommands) == 0)
- {
- outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& peer -> outgoingReliableCommands));
+ peer -> channels = NULL;
+ peer -> channelCount = 0;
+}
- if (outgoingCommand -> packet != NULL)
- {
- -- outgoingCommand -> packet -> referenceCount;
+void
+enet_peer_ping (ENetPeer * peer)
+{
+ ENetProtocol command;
- if (outgoingCommand -> packet -> referenceCount == 0)
- enet_packet_destroy (outgoingCommand -> packet);
- }
-
- enet_free (outgoingCommand);
- }
+ if (peer -> state != ENET_PEER_STATE_CONNECTED)
+ return;
- while (enet_list_empty (& peer -> outgoingUnreliableCommands) == 0)
- {
- outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& peer -> outgoingUnreliableCommands));
+ command.header.command = ENET_PROTOCOL_COMMAND_PING;
+ command.header.channelID = 0xFF;
+ command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
+ command.header.commandLength = sizeof (ENetProtocolPing);
+
+ enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+}
- if (outgoingCommand -> packet != NULL)
- {
- -- outgoingCommand -> packet -> referenceCount;
+void
+enet_peer_disconnect (ENetPeer * peer)
+{
+ ENetProtocol command;
- if (outgoingCommand -> packet -> referenceCount == 0)
- enet_packet_destroy (outgoingCommand -> packet);
- }
+ if (peer -> state == ENET_PEER_STATE_DISCONNECTING ||
+ peer -> state == ENET_PEER_STATE_DISCONNECTED)
+ return;
- enet_free (outgoingCommand);
- }
+ peer -> state = ENET_PEER_STATE_DISCONNECTING;
- while (enet_list_empty (& peer -> incomingReliableCommands) == 0)
- {
- incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (& peer -> incomingReliableCommands));
+ command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT;
+ command.header.channelID = 0xFF;
+ command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
+ command.header.commandLength = sizeof (ENetProtocolDisconnect);
- if (incomingCommand -> packet != NULL)
- {
- -- incomingCommand -> packet -> referenceCount;
-
- if (incomingCommand -> packet -> referenceCount == 0)
- enet_packet_destroy (incomingCommand -> packet);
- }
-
- enet_free (incomingCommand);
- }
+ enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+}
- while (enet_list_empty (& peer -> incomingUnreliableCommands) == 0)
- {
- incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (& peer -> incomingUnreliableCommands));
+ENetAcknowledgement *
+enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, uint32 sentTime)
+{
+ ENetAcknowledgement * acknowledgement;
- if (incomingCommand -> packet != NULL)
- {
- -- incomingCommand -> packet -> referenceCount;
+ peer -> outgoingDataTotal += sizeof (ENetProtocolAcknowledge);
- if (incomingCommand -> packet -> referenceCount == 0)
- enet_packet_destroy (incomingCommand -> packet);
- }
+ acknowledgement = (ENetAcknowledgement *) enet_malloc (sizeof (ENetAcknowledgement));
- enet_free (incomingCommand);
- }
+ acknowledgement -> sentTime = sentTime;
+ acknowledgement -> command = * command;
+
+ enet_list_insert (enet_list_end (& peer -> acknowledgements), acknowledgement);
+
+ return acknowledgement;
}
-void
-enet_peer_ping (ENetPeer * peer)
+ENetOutgoingCommand *
+enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, uint32 offset, uint16 length)
{
+ ENetChannel * channel = & peer -> channels [command -> header.channelID];
ENetOutgoingCommand * outgoingCommand;
+ peer -> outgoingDataTotal += command -> header.commandLength + length;
+
outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
- ++ peer -> outgoingReliableSequenceNumber;
+ if (command -> header.channelID == 0xFF)
+ {
+ ++ peer -> outgoingReliableSequenceNumber;
- outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber;
- outgoingCommand -> unreliableSequenceNumber = 0;
+ outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber;
+ outgoingCommand -> unreliableSequenceNumber = 0;
+ }
+ else
+ if (command -> header.flags & ENET_PROTOCOL_FLAG_ACKNOWLEDGE)
+ {
+ ++ channel -> outgoingReliableSequenceNumber;
+
+ outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
+ outgoingCommand -> unreliableSequenceNumber = 0;
+ }
+ else
+ {
+ ++ channel -> outgoingUnreliableSequenceNumber;
+
+ outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
+ outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber;
+ }
+
outgoingCommand -> sentTime = 0;
outgoingCommand -> roundTripTimeout = 0;
outgoingCommand -> roundTripTimeoutLimit = 0;
- outgoingCommand -> fragmentOffset = 0;
- outgoingCommand -> fragmentLength = 0;
- outgoingCommand -> packet = NULL;
-
- outgoingCommand -> command.header.command = ENET_PROTOCOL_COMMAND_PING;
- outgoingCommand -> command.header.flags = 0;
- outgoingCommand -> command.header.commandLength = sizeof (ENetProtocolPing);
- outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_32 (peer -> outgoingReliableSequenceNumber);
+ outgoingCommand -> fragmentOffset = offset;
+ outgoingCommand -> fragmentLength = length;
+ outgoingCommand -> packet = packet;
+ outgoingCommand -> command = * command;
+ outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_32 (outgoingCommand -> reliableSequenceNumber);
+
+ if (packet != NULL)
+ ++ packet -> referenceCount;
- enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
+ if (command -> header.flags & ENET_PROTOCOL_FLAG_ACKNOWLEDGE)
+ enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
+ else
+ enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
+
+ return outgoingCommand;
}
-void
-enet_peer_disconnect (ENetPeer * peer)
+ENetIncomingCommand *
+enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, uint32 fragmentCount)
{
- ENetOutgoingCommand * outgoingCommand;
+ ENetChannel * channel = & peer -> channels [command -> header.channelID];
+ uint32 unreliableSequenceNumber = 0;
+ ENetIncomingCommand * incomingCommand;
+ ENetListIterator currentCommand;
- if (peer -> state == ENET_PEER_STATE_DISCONNECTING ||
- peer -> state == ENET_PEER_STATE_DISCONNECTED)
- return;
+ if (command -> header.command == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE)
+ unreliableSequenceNumber = ENET_NET_TO_HOST_32 (command -> sendUnreliable.unreliableSequenceNumber);
- peer -> state = ENET_PEER_STATE_DISCONNECTING;
+ if (unreliableSequenceNumber == 0)
+ {
+ for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
+ currentCommand != enet_list_end (& channel -> incomingReliableCommands);
+ currentCommand = enet_list_previous (currentCommand))
+ {
+ incomingCommand = (ENetIncomingCommand *) currentCommand;
- outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
+ if (incomingCommand -> reliableSequenceNumber <= command -> header.reliableSequenceNumber)
+ {
+ if (incomingCommand -> reliableSequenceNumber < command -> header.reliableSequenceNumber)
+ break;
- ++ peer -> outgoingReliableSequenceNumber;
+ goto freePacket;
+ }
+ }
+ }
+ else
+ {
+ if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+ goto freePacket;
- outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber;
- outgoingCommand -> unreliableSequenceNumber = 0;
- outgoingCommand -> sentTime = 0;
- outgoingCommand -> roundTripTimeout = 0;
- outgoingCommand -> roundTripTimeoutLimit = 0;
- outgoingCommand -> fragmentOffset = 0;
- outgoingCommand -> fragmentLength = 0;
- outgoingCommand -> packet = NULL;
-
- outgoingCommand -> command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT;
- outgoingCommand -> command.header.flags = 0;
- outgoingCommand -> command.header.commandLength = sizeof (ENetProtocolDisconnect);
- outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_32 (peer -> outgoingReliableSequenceNumber);
+ if (unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber)
+ goto freePacket;
+
+ for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
+ currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
+ currentCommand = enet_list_previous (currentCommand))
+ {
+ incomingCommand = (ENetIncomingCommand *) currentCommand;
+
+ if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber)
+ {
+ if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber)
+ break;
- enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
+ goto freePacket;
+ }
+ }
+ }
+
+ incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand));
+
+ incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber;
+ incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber;
+ incomingCommand -> command = * command;
+ incomingCommand -> fragmentCount = fragmentCount;
+ incomingCommand -> fragmentsRemaining = fragmentCount;
+ incomingCommand -> packet = packet;
+
+ if (fragmentCount > 0)
+ incomingCommand -> fragments = (uint32 *) enet_calloc ((fragmentCount + 31) / 32, sizeof (uint32));
+ else
+ incomingCommand -> fragments = NULL;
+
+ if (packet != NULL)
+ ++ packet -> referenceCount;
+
+ enet_list_insert (enet_list_next (currentCommand), incomingCommand);
+
+ return incomingCommand;
+
+freePacket:
+ if (packet != NULL)
+ {
+ if (packet -> referenceCount == 0)
+ enet_packet_destroy (packet);
+ }
+
+ return NULL;
}
-
-
Index: protocol.c
===================================================================
RCS file: /home/enet/cvsroot/enet/protocol.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- protocol.c 2002/02/10 22:24:41 1.2
+++ protocol.c 2002/06/08 02:29:12 1.3
@@ -8,6 +8,7 @@
enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
{
ENetPeer * currentPeer = host -> lastServicedPeer;
+ ENetChannel * channel;
do
{
@@ -19,119 +20,55 @@
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
continue;
[...1036 lines suppressed...]
return -1;
@@ -1136,6 +983,8 @@
void
enet_host_flush (ENetHost * host)
{
+ timeCurrent = enet_time_get ();
+
enet_protocol_send_outgoing_commands (host, NULL, 0);
}
@@ -1168,6 +1017,9 @@
do
{
+ if (timeCurrent - host -> bandwidthThrottleEpoch >= ENET_HOST_BANDWIDTH_THROTTLE_EPOCH)
+ enet_host_bandwidth_throttle (host);
+
switch (enet_protocol_receive_incoming_commands (host, event))
{
case 1:
Index: unix.c
===================================================================
RCS file: /home/enet/cvsroot/enet/unix.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- unix.c 2002/02/10 21:27:03 1.1
+++ unix.c 2002/06/08 02:29:12 1.2
@@ -28,8 +28,6 @@
int
enet_initialize (void)
{
- srand (time (NULL));
-
return 0;
}
@@ -91,9 +89,9 @@
}
ENetSocket
-enet_socket_create (const ENetAddress * address)
+enet_socket_create (ENetSocketType type, const ENetAddress * address)
{
- ENetSocket newSocket = socket (PF_INET, SOCK_DGRAM, 0);
+ ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
int nonBlocking = 1,
receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE;
struct sockaddr_in sin;
@@ -101,14 +99,17 @@
if (newSocket == ENET_SOCKET_NULL)
return ENET_SOCKET_NULL;
+ if (type == ENET_SOCKET_TYPE_DATAGRAM)
+ {
#ifdef HAS_FCNTL
- fcntl (newSocket, F_SETFL, O_NONBLOCK | fcntl (newSocket, F_GETFL));
+ fcntl (newSocket, F_SETFL, O_NONBLOCK | fcntl (newSocket, F_GETFL));
#else
- ioctl (newSocket, FIONBIO, & nonBlocking);
+ ioctl (newSocket, FIONBIO, & nonBlocking);
#endif
-
- setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int));
+ setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int));
+ }
+
if (address == NULL)
return newSocket;
@@ -118,7 +119,9 @@
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
- if (bind (newSocket,
+ if ((type == ENET_SOCKET_TYPE_STREAM &&
+ listen (newSocket, SOMAXCONN) == -1) ||
+ bind (newSocket,
(struct sockaddr *) & sin,
sizeof (struct sockaddr_in)) == -1)
{
@@ -130,6 +133,43 @@
return newSocket;
}
+int
+enet_socket_connect (ENetSocket socket, const ENetAddress * address)
+{
+ struct sockaddr_in sin;
+
+ memset (& sin, 0, sizeof (struct sockaddr_in));
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+ sin.sin_addr.s_addr = address -> host;
+
+ return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
+}
+
+ENetSocket
+enet_socket_accept (ENetSocket socket, ENetAddress * address)
+{
+ int result;
+ struct sockaddr_in sin;
+ socklen_t sinLength = sizeof (struct sockaddr_in);
+
+ result = accept (socket,
+ address != NULL ? (struct sockaddr *) & sin : NULL,
+ address != NULL ? & sinLength : NULL);
+
+ if (result == -1)
+ return ENET_SOCKET_NULL;
+
+ if (address != NULL)
+ {
+ address -> host = (uint32) sin.sin_addr.s_addr;
+ address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+ }
+
+ return result;
+}
+
void
enet_socket_destroy (ENetSocket socket)
{
@@ -146,14 +186,18 @@
struct sockaddr_in sin;
int sentLength;
- sin.sin_family = AF_INET;
- sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
- sin.sin_addr.s_addr = address -> host;
-
memset (& msgHdr, 0, sizeof (struct msghdr));
+
+ if (address != NULL)
+ {
+ sin.sin_family = AF_INET;
+ sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+ sin.sin_addr.s_addr = address -> host;
+
+ msgHdr.msg_name = & sin;
+ msgHdr.msg_namelen = sizeof (struct sockaddr_in);
+ }
- msgHdr.msg_name = & sin;
- msgHdr.msg_namelen = sizeof (struct sockaddr_in);
msgHdr.msg_iov = (struct iovec *) buffers;
msgHdr.msg_iovlen = bufferCount;
@@ -182,8 +226,12 @@
memset (& msgHdr, 0, sizeof (struct msghdr));
- msgHdr.msg_name = & sin;
- msgHdr.msg_namelen = sizeof (struct sockaddr_in);
+ if (address != NULL)
+ {
+ msgHdr.msg_name = & sin;
+ msgHdr.msg_namelen = sizeof (struct sockaddr_in);
+ }
+
msgHdr.msg_iov = (struct iovec *) buffers;
msgHdr.msg_iovlen = bufferCount;
@@ -202,8 +250,11 @@
return -1;
#endif
- address -> host = (uint32) sin.sin_addr.s_addr;
- address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+ if (address != NULL)
+ {
+ address -> host = (uint32) sin.sin_addr.s_addr;
+ address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+ }
return recvLength;
}
Index: win32.c
===================================================================
RCS file: /home/enet/cvsroot/enet/win32.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- win32.c 2002/02/10 22:24:41 1.2
+++ win32.c 2002/06/08 02:29:12 1.3
@@ -22,8 +22,6 @@
return -1;
}
- srand (time (NULL));
-
return 0;
}
@@ -78,9 +76,9 @@
}
ENetSocket
-enet_socket_create (const ENetAddress * address)
+enet_socket_create (ENetSocketType type, const ENetAddress * address)
{
- ENetSocket newSocket = socket (PF_INET, SOCK_DGRAM, 0);
+ ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
int nonBlocking = 1,
receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE;
struct sockaddr_in sin;
@@ -88,9 +86,12 @@
if (newSocket == ENET_SOCKET_NULL)
return ENET_SOCKET_NULL;
- ioctlsocket (newSocket, FIONBIO, & nonBlocking);
+ if (type == ENET_SOCKET_TYPE_DATAGRAM)
+ {
+ ioctlsocket (newSocket, FIONBIO, & nonBlocking);
- setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int));
+ setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int));
+ }
memset (& sin, 0, sizeof (struct sockaddr_in));
@@ -107,7 +108,9 @@
sin.sin_addr.s_addr = INADDR_ANY;
}
- if (bind (newSocket,
+ if ((type == ENET_SOCKET_TYPE_STREAM &&
+ listen (newSocket, SOMAXCONN) == SOCKET_ERROR) ||
+ bind (newSocket,
(struct sockaddr *) & sin,
sizeof (struct sockaddr_in)) == SOCKET_ERROR)
{
@@ -119,6 +122,43 @@
return newSocket;
}
+int
+enet_socket_connect (ENetSocket socket, const ENetAddress * address)
+{
+ struct sockaddr_in sin;
+
+ memset (& sin, 0, sizeof (struct sockaddr_in));
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+ sin.sin_addr.s_addr = address -> host;
+
+ return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
+}
+
+ENetSocket
+enet_socket_accept (ENetSocket socket, ENetAddress * address)
+{
+ int result;
+ struct sockaddr_in sin;
+ int sinLength = sizeof (struct sockaddr_in);
+
+ result = accept (socket,
+ address != NULL ? (struct sockaddr *) & sin : NULL,
+ address != NULL ? & sinLength : NULL);
+
+ if (result == -1)
+ return ENET_SOCKET_NULL;
+
+ if (address != NULL)
+ {
+ address -> host = (uint32) sin.sin_addr.s_addr;
+ address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+ }
+
+ return result;
+}
+
void
enet_socket_destroy (ENetSocket socket)
{
@@ -134,17 +174,20 @@
struct sockaddr_in sin;
DWORD sentLength;
- sin.sin_family = AF_INET;
- sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
- sin.sin_addr.s_addr = address -> host;
+ if (address != NULL)
+ {
+ sin.sin_family = AF_INET;
+ sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+ sin.sin_addr.s_addr = address -> host;
+ }
if (WSASendTo (socket,
(LPWSABUF) buffers,
(DWORD) bufferCount,
& sentLength,
0,
- (struct sockaddr *) & sin,
- sizeof (struct sockaddr_in),
+ address != NULL ? (struct sockaddr *) & sin : 0,
+ address != NULL ? sizeof (struct sockaddr_in) : 0,
NULL,
NULL) == SOCKET_ERROR)
{
@@ -173,13 +216,17 @@
(DWORD) bufferCount,
& recvLength,
& flags,
- (struct sockaddr *) & sin,
- & sinLength,
+ address != NULL ? (struct sockaddr *) & sin : NULL,
+ address != NULL ? & sinLength : NULL,
NULL,
NULL) == SOCKET_ERROR)
{
- if (WSAGetLastError () == WSAEWOULDBLOCK)
- return 0;
+ switch (WSAGetLastError ())
+ {
+ case WSAEWOULDBLOCK:
+ case WSAECONNRESET:
+ return 0;
+ }
return -1;
}
@@ -187,8 +234,11 @@
if (flags & MSG_PARTIAL)
return -1;
- address -> host = (uint32) sin.sin_addr.s_addr;
- address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+ if (address != NULL)
+ {
+ address -> host = (uint32) sin.sin_addr.s_addr;
+ address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+ }
return (int) recvLength;
}