From 8933b795003f8ad202fce6e553191be8932a37b6 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Fri, 30 May 2008 19:56:10 +0000 Subject: zlib support --- src/core/netclient.cc | 62 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 20 deletions(-) (limited to 'src/core/netclient.cc') diff --git a/src/core/netclient.cc b/src/core/netclient.cc index b90f164..dc4a0bd 100644 --- a/src/core/netclient.cc +++ b/src/core/netclient.cc @@ -4,6 +4,8 @@ the terms of the GNU General Public License version 2 */ +#include + #include #include @@ -87,29 +89,23 @@ void NetClient::retreive(std::string & message) { // receive data and decode it into lines void NetClient::receive(char *data) { - std::string datablock; - datablock.assign(data); - - if (!datablock.size()) - return; + const char *c = data; - while(datablock.size() > 0 ) { - // scan the datablock for enters - if (datablock[0] == '\n' || datablock[0] == '\r') { - // TODO detect "begin binary block" message for zlib compression + while (*c) { + if (( *c == '\n') || (*c == '\r')) { if (messageblock.size() > 0 ) { recvq.push_back(messageblock); messageblock.clear(); } } else { if (messageblock.size() < FRAMESIZE) { - messageblock.append(datablock.substr(0,1)); + messageblock += *c; } else { con_warn << "Incoming message exceeds " << FRAMESIZE << " bytes!\n"; messageblock.clear(); } } - datablock.erase(0,1); + c++; } client_timeout = application()->time(); @@ -128,16 +124,41 @@ void NetClient::transmit(int serverfd) } else { return; } - } else if (sendq.size() >= FRAMESIZE) { - con_warn << "Outgoing message exceeds " << FRAMESIZE -1 << " bytes!\n"; - //sendq.clear(); - //return; + } else if (sendq.size() >= BLOCKSIZE - 16 ) { + con_warn << host() << ":" << port() << " outgoing data exceeds " << BLOCKSIZE - 16 << " bytes!\n"; + sendq.clear(); + return; } - ssize_t bytes_sent = 0; + char zbuf[BLOCKSIZE]; + const char *data = 0; + size_t compressed_size = BLOCKSIZE - 5; + size_t total_size = 0; + + memset(zbuf,0, sizeof(zbuf)); + + Stats::network_uncompressed_bytes_sent += sendq.size(); + + // zlib compress + int status = compress((Bytef*)(zbuf+4), &compressed_size, (Bytef*)sendq.c_str(), sendq.size()); - while (sendq.size() && !error()) { - bytes_sent = ::sendto(serverfd, sendq.c_str(), sendq.size()+1, 0, + if ((status == Z_OK) && (compressed_size + 4 < sendq.size())) { + // add a header to the compress packet + data = zbuf; + total_size = compressed_size + 4; + zbuf[0] = '\xff'; + zbuf[1] = '\xff'; + zbuf[2] = compressed_size % 256; + zbuf[3] = compressed_size >> 8; + } else { + data = sendq.c_str(); + total_size = sendq.size(); + } + + size_t total_sent = 0; + + while (total_sent < total_size && !error()) { + ssize_t bytes_sent = ::sendto(serverfd, data, total_size - total_sent, 0, (struct sockaddr *)&client_addr, sizeof(client_addr)); if (bytes_sent < 0) { @@ -145,11 +166,12 @@ void NetClient::transmit(int serverfd) return; } - sendq.erase(0, bytes_sent); + total_sent += bytes_sent; + data += bytes_sent; Stats::network_bytes_sent += bytes_sent; } - sendq.clear(); + sendq.clear(); client_keepalive = application()->time(); } -- cgit v1.2.3