From c97168bd5113fe726de42a4249df58c679e42240 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 25 Jun 2008 02:02:21 +0200 Subject: Neuen Receive-Stack implementiert --- src/Net/Connection.cpp | 128 ++++++++++++++++++++++++++----------------------- 1 file changed, 69 insertions(+), 59 deletions(-) (limited to 'src/Net/Connection.cpp') diff --git a/src/Net/Connection.cpp b/src/Net/Connection.cpp index 31821ac..768d827 100644 --- a/src/Net/Connection.cpp +++ b/src/Net/Connection.cpp @@ -18,71 +18,88 @@ */ #include "Connection.h" -#include "Packet.h" namespace Mad { namespace Net { -bool Connection::send(const Packet &packet) { +void Connection::packetHeaderReceiveHandler(const void *data, unsigned long length) { + if(length != sizeof(Packet::Data)) + return; // Error... disconnect? + + header = *reinterpret_cast(data); + + if(header.length == 0) { + signal(this, Packet(header.type, header.requestId)); + + enterReceiveLoop(); + } + else { + rawReceive(header.length, sigc::mem_fun(this, &Connection::packetDataReceiveHandler)); + } +} + +void Connection::packetDataReceiveHandler(const void *data, unsigned long length) { + if(length != header.length) + return; // Error... disconnect? + + signal(this, Packet(header.type, header.requestId, data, length)); + + enterReceiveLoop(); +} + +void Connection::doReceive() { if(!isConnected()) - return false; + return; + + if(!dataPending()) + return; - const unsigned char *data = reinterpret_cast(packet.getRawData()); - unsigned long dataLength = packet.getRawDataLength(); + if(receiveComplete()) + return; - while(dataLength > 0) { - ssize_t ret = gnutls_record_send(getSession(), data, dataLength); + ssize_t ret = gnutls_record_recv(getSession(), transR.data+transR.transmitted, transR.length-transR.transmitted); + + if(ret < 0) { + if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) + return; - if(ret < 0) { - if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) - continue; - - return false; - } + // Error... disconnect? + return; + } + + transR.transmitted += ret; + + if(receiveComplete()) { + transR.notify(transR.data, transR.length); - data += ret; - dataLength -= ret; + delete [] transR.data; + transR.data = 0; } +} + +bool Connection::rawReceive(unsigned long length, + const sigc::slot ¬ify) +{ + if(!isConnected()) + return false; + + if(!receiveComplete()) + return false; + + transR.data = new unsigned char[length]; + transR.length = length; + transR.transmitted = 0; + transR.notify = notify; return true; } -bool Connection::receive() { - unsigned char *headerData = reinterpret_cast(&header); - ssize_t ret; - +bool Connection::rawSend(const unsigned char *data, unsigned long length) { if(!isConnected()) return false; - while(true) { - if(!dataPending()) - return false; - - if(read < sizeof(Packet::Data)) { - ret = gnutls_record_recv(getSession(), headerData+read, sizeof(Packet::Data)-read); - - if(ret < 0) { - if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) - continue; - - return false; - } - - read += ret; - - if(read < sizeof(Packet::Data)) - continue; - - if(!header.length) { - signal(this, Packet(header.type, header.requestId)); - - return true; - } - - data = new unsigned char[header.length]; - } - - ret = gnutls_record_recv(getSession(), data+read-sizeof(Packet::Data), header.length+sizeof(Packet::Data)-read); + while(length > 0) { + ssize_t ret = gnutls_record_send(getSession(), data, length); if(ret < 0) { if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) @@ -91,18 +108,11 @@ bool Connection::receive() { return false; } - read += ret; - - if(read < header.length+sizeof(Packet::Data)) - continue; - - signal(this, Packet(header.type, header.requestId, data, header.length)); - - delete [] data; - data = 0; - - return true; + data += ret; + length -= ret; } + + return true; } } -- cgit v1.2.3