- Added selective compression of network packets. Interestingly, most packets

don't actually compress all that well, even the ones that aren't too short
  to possibly compress. (Maybe make the whole thing one long, never-ending
  zlib data stream with Z_SYNC_FLUSH used to chunk things at packet
  boundaries? That would probably help the compression ratio, but it would
  require changing the way the netcode determines sequence, which would be
  a much more invasive change.)


SVN r1438 (trunk)
This commit is contained in:
Randy Heit 2009-02-22 05:05:58 +00:00
commit 10c31b82cb
4 changed files with 108 additions and 38 deletions

View file

@ -64,7 +64,9 @@
#include "i_net.h"
// As per http://support.microsoft.com/kb/q192599/ the standard
// size for network buffers is 8k.
#define TRANSMIT_SIZE 8000
/* [Petteri] Get more portable: */
#ifndef __WIN32__
@ -133,6 +135,8 @@ struct PreGamePacket
} machines[MAXNETNODES];
};
BYTE TransmitBuffer[TRANSMIT_SIZE];
//
// UDPsocket
//
@ -191,11 +195,47 @@ void PacketSend (void)
{
int c;
//printf ("sending %i\n",gametic);
c = sendto (mysocket , (const char*)doomcom.data, doomcom.datalength
,0,(sockaddr *)&sendaddress[doomcom.remotenode]
,sizeof(sendaddress[doomcom.remotenode]));
// FIXME: Catch this before we've overflown the buffer. With long chat
// text and lots of backup tics, it could conceivably happen. (Though
// apparently it hasn't yet, which is good.)
if (doomcom.datalength > MAX_MSGLEN)
{
I_FatalError("Netbuffer overflow!");
}
uLong size = TRANSMIT_SIZE - 1;
if (doomcom.datalength >= 10)
{
assert(!(doomcom.data[0] & NCMD_COMPRESSED));
TransmitBuffer[0] = doomcom.data[0] | NCMD_COMPRESSED;
c = compress2(TransmitBuffer + 1, &size, doomcom.data + 1, doomcom.datalength - 1, 9);
size += 1;
}
else
{
c = -1; // Just some random error code to avoid sending the compressed buffer.
}
if (c == Z_OK && size < (uLong)doomcom.datalength)
{
// Printf("send %lu/%d\n", size, doomcom.datalength);
c = sendto(mysocket, (char *)TransmitBuffer, size,
0, (sockaddr *)&sendaddress[doomcom.remotenode],
sizeof(sendaddress[doomcom.remotenode]));
}
else
{
if (doomcom.datalength > TRANSMIT_SIZE)
{
I_Error("Net compression failed (zlib error %d)", c);
}
else
{
// Printf("send %d\n", doomcom.datalength);
c = sendto(mysocket, (char *)doomcom.data, doomcom.datalength,
0, (sockaddr *)&sendaddress[doomcom.remotenode],
sizeof(sendaddress[doomcom.remotenode]));
}
}
// if (c == -1)
// I_Error ("SendPacket error: %s",strerror(errno));
}
@ -212,8 +252,8 @@ void PacketGet (void)
int node;
fromlen = sizeof(fromaddress);
c = recvfrom (mysocket, (char*)doomcom.data, MAX_MSGLEN, 0
, (sockaddr *)&fromaddress, &fromlen);
c = recvfrom (mysocket, (char*)TransmitBuffer, TRANSMIT_SIZE, 0,
(sockaddr *)&fromaddress, &fromlen);
node = FindNode (&fromaddress);
if (node >= 0 && c == SOCKET_ERROR)
@ -239,6 +279,26 @@ void PacketGet (void)
return;
}
}
else if (c > 0)
{
doomcom.data[0] = TransmitBuffer[0] & ~NCMD_COMPRESSED;
if (TransmitBuffer[0] & NCMD_COMPRESSED)
{
uLongf msgsize = MAX_MSGLEN - 1;
int err = uncompress(doomcom.data + 1, &msgsize, TransmitBuffer + 1, c - 1);
// Printf("recv %d/%lu\n", c, msgsize + 1);
if (err != Z_OK)
{
I_Error("Net decompression failed (zlib error %d)\n", err);
}
c = msgsize + 1;
}
else
{
// Printf("recv %d\n", c);
memcpy(doomcom.data + 1, TransmitBuffer + 1, c - 1);
}
}
doomcom.remotenode = node;
doomcom.datalength = (short)c;