ref: 3acf0268978b3eb7354cf74385673d16522e30d0
parent: cdbc892c80a42bf0bbd3559831eb9675b5f019f4
author: Simon Howard <[email protected]>
date: Sun Jan 1 19:54:17 EST 2006
Fix packet not freed back after being sent. Code to disconnect clients from the server side. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 242
--- a/src/net_client.c
+++ b/src/net_client.c
@@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
-// $Id: net_client.c 239 2006-01-02 00:00:08Z fraggle $
+// $Id: net_client.c 242 2006-01-02 00:54:17Z fraggle $
//
// Copyright(C) 2005 Simon Howard
//
@@ -21,6 +21,10 @@
// 02111-1307, USA.
//
// $Log$
+// Revision 1.6 2006/01/02 00:54:17 fraggle
+// Fix packet not freed back after being sent.
+// Code to disconnect clients from the server side.
+//
// Revision 1.5 2006/01/02 00:00:08 fraggle
// Neater prefixes: NET_Client -> NET_CL_. NET_Server -> NET_SV_.
//
@@ -139,10 +143,14 @@
NET_SendPacket(server_addr, reply);
NET_SendPacket(server_addr, reply);
NET_SendPacket(server_addr, reply);
+ NET_FreePacket(reply);
client_state = CLIENT_STATE_DISCONNECTED;
- I_Error("Disconnected from server.\n");
+ //I_Error("Disconnected from server.\n");
+ fprintf(stderr, "Disconnected from server.\n");
+
+ // Now what?
}
// parse a DISCONNECT_ACK packet
--- a/src/net_server.c
+++ b/src/net_server.c
@@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
-// $Id: net_server.c 239 2006-01-02 00:00:08Z fraggle $
+// $Id: net_server.c 242 2006-01-02 00:54:17Z fraggle $
//
// Copyright(C) 2005 Simon Howard
//
@@ -21,6 +21,10 @@
// 02111-1307, USA.
//
// $Log$
+// Revision 1.6 2006/01/02 00:54:17 fraggle
+// Fix packet not freed back after being sent.
+// Code to disconnect clients from the server side.
+//
// Revision 1.5 2006/01/02 00:00:08 fraggle
// Neater prefixes: NET_Client -> NET_CL_. NET_Server -> NET_SV_.
//
@@ -90,6 +94,12 @@
static net_client_t clients[MAXNETNODES];
static net_context_t *server_context;
+static void NET_SV_DisconnectClient(net_client_t *client)
+{
+ client->state = CLIENT_STATE_DISCONNECTING;
+ client->last_send_time = -1;
+}
+
static boolean ClientConnected(net_client_t *client)
{
// Check that the client is properly connected: ie. not in the
@@ -162,8 +172,8 @@
// parse a SYN from a client(initiating a connection)
static void NET_SV_ParseSYN(net_packet_t *packet,
- net_client_t *client,
- net_addr_t *addr)
+ net_client_t *client,
+ net_addr_t *addr)
{
unsigned int magic;
int i;
@@ -194,11 +204,10 @@
{
if (!clients[i].active)
{
- clients[i].active = true;
- clients[i].addr = addr;
- clients[i].state = CLIENT_STATE_WAITING_ACK;
- clients[i].num_retries = 0;
client = &clients[i];
+ client->active = true;
+ client->addr = addr;
+ client->state = CLIENT_STATE_DISCONNECTED;
break;
}
}
@@ -209,6 +218,15 @@
}
}
+ // Set into the correct state if necessary
+ // Allow immediate reconnects from clients which just disconnected.
+
+ if (client->state == CLIENT_STATE_DISCONNECTED)
+ {
+ client->state = CLIENT_STATE_WAITING_ACK;
+ client->num_retries = 0;
+ }
+
if (client->state == CLIENT_STATE_WAITING_ACK)
{
// force an acknowledgement
@@ -235,6 +253,10 @@
// force a waiting data packet to be sent immediately
client->last_send_time = -1;
+
+ // test: disconnect straight away
+
+ NET_SV_DisconnectClient(client);
}
}
@@ -267,8 +289,30 @@
// and cleaned up from the clients list.
client->state = CLIENT_STATE_DISCONNECTED;
+}
- printf("client %i disconnected\n", client-clients);
+// Parse a DISCONNECT_ACK packet
+
+static void NET_SV_ParseDisconnectACK(net_packet_t *packet,
+ net_client_t *client)
+{
+ // Sanity check
+
+ if (client == NULL)
+ {
+ return;
+ }
+
+ if (client->state == CLIENT_STATE_DISCONNECTING)
+ {
+ // We have received an acknowledgement to our disconnect
+ // request. Client has been disconnected successfully.
+
+ // Place into the DISCONNECTED state to allow for cleanup.
+
+ client->state = CLIENT_STATE_DISCONNECTED;
+ client->last_send_time = I_GetTimeMS();
+ }
}
// Process a packet received by the server
@@ -291,6 +335,8 @@
return;
}
+ //printf("SV: %p: %i\n", client, packet_type);
+
switch (packet_type)
{
case NET_PACKET_TYPE_SYN:
@@ -306,6 +352,9 @@
case NET_PACKET_TYPE_DISCONNECT:
NET_SV_ParseDisconnect(packet, client);
break;
+ case NET_PACKET_TYPE_DISCONNECT_ACK:
+ NET_SV_ParseDisconnectACK(packet, client);
+ break;
default:
// unknown packet type
@@ -358,7 +407,7 @@
if (client->state == CLIENT_STATE_WAITING_ACK)
{
if (client->last_send_time < 0
- || I_GetTime() - client->last_send_time > 35)
+ || I_GetTimeMS() - client->last_send_time > 1000)
{
// it has been a second since the last ACK was sent, and
// still no reply.
@@ -371,7 +420,7 @@
NET_WriteInt16(packet, NET_PACKET_TYPE_ACK);
NET_SendPacket(client->addr, packet);
NET_FreePacket(packet);
- client->last_send_time = I_GetTime();
+ client->last_send_time = I_GetTimeMS();
++client->num_retries;
}
@@ -384,11 +433,10 @@
}
}
}
-
- // waiting for the game to start
-
- if (client->state == CLIENT_STATE_WAITING_START)
+ else if (client->state == CLIENT_STATE_WAITING_START)
{
+ // Waiting for the game to start
+
// Send information once every second
if (client->last_send_time < 0
@@ -397,17 +445,50 @@
NET_SV_SendWaitingData(client);
}
}
+ else if (client->state == CLIENT_STATE_DISCONNECTING)
+ {
+ // Waiting for a reply to our DISCONNECT request.
- // Client has disconnected.
- //
- // See NET_SV_ParseDisconnect() above.
+ if (client->last_send_time < 0
+ || I_GetTimeMS() - client->last_send_time > 1000)
+ {
+ // it has been a second since the last disconnect packet
+ // was sent, and still no reply.
- if (client->state == CLIENT_STATE_DISCONNECTED)
+ if (client->num_retries < MAX_RETRIES)
+ {
+ // send another disconnect
+
+ packet = NET_NewPacket(10);
+ NET_WriteInt16(packet, NET_PACKET_TYPE_DISCONNECT);
+ NET_SendPacket(client->addr, packet);
+ NET_FreePacket(packet);
+ client->last_send_time = I_GetTimeMS();
+
+ ++client->num_retries;
+ }
+ else
+ {
+ // No more retries allowed.
+ // Force disconnect.
+
+ client->active = false;
+ NET_FreeAddress(client->addr);
+ }
+ }
+
+ }
+ else if (client->state == CLIENT_STATE_DISCONNECTED)
{
+ // Client has disconnected.
+ //
+ // See NET_SV_ParseDisconnect() above.
+
// Remove from the list after five seconds
if (I_GetTimeMS() - client->last_send_time > 5000)
{
+ //printf("SV: %p: deactivated\n", client);
client->active = false;
NET_FreeAddress(client->addr);
}