Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-05-30 19:56:10 +0000
committerStijn Buys <ingar@osirion.org>2008-05-30 19:56:10 +0000
commit8933b795003f8ad202fce6e553191be8932a37b6 (patch)
treebfb460cbf9261b44deabfd469046a14a95c8d16c /src/core/netclient.cc
parentf71901eeab126bb4b7e2552dd2edf0b34632c683 (diff)
zlib support
Diffstat (limited to 'src/core/netclient.cc')
-rw-r--r--src/core/netclient.cc62
1 files changed, 42 insertions, 20 deletions
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 <zlib.h>
+
#include <iostream>
#include <sstream>
@@ -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();
}