X-Git-Url: http://developer.intra2net.com/git/?p=libt2n;a=blobdiff_plain;f=src%2Fconnection.cpp;h=30a0b19246dae9e4f277f561f135b00800457999;hp=b4cf198abc9fe514af6bb06c831b1c934b47a8a9;hb=e1614a6d1d9c022b83c0aa8cdb948bd7dc98ff23;hpb=a64066eb0e456c92c4c06959616443e531d4b39d diff --git a/src/connection.cpp b/src/connection.cpp index b4cf198..30a0b19 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -103,6 +104,39 @@ unsigned int connection::peek_packet(std::string& data) return psize; } +/// remove all data from buffer that is not a complete packet +void connection::remove_incomplete_packets() +{ + std::string::size_type p=0; + std::string::size_type end=buffer.size(); + + while (p < end) + { + // not enough space for size information -> no packet + if (p+sizeof(packet_size_indicator) > end) + break; + + packet_size_indicator psize=ntohl(*((packet_size_indicator*)(buffer.data()+p))); + + if (p+sizeof(packet_size_indicator)+psize > end) + { + // incomplete packet + break; + } + else + { + // move p to where the next packet will start + p+=sizeof(packet_size_indicator)+psize; + } + } + + if (p < end) + { + // incomplete packets there, remove them + buffer.erase(p); + } +} + /// send a blob to the peer void connection::write(const std::string& data) { @@ -125,9 +159,6 @@ void connection::write(const std::string& data) */ void connection::add_callback(callback_event_type event, const boost::function& func) { - if (event == new_connection) - throw std::logic_error("new_connection callback not allowed for server_connections"); - callbacks[event].push_back(func); } @@ -154,5 +185,24 @@ std::list > connection::get_callback_list(callback_even return callbacks[event]; } +/** @brief reopen a already closed connection, removes incomplete packets from the buffer + + @note Only call when the connection is closed. + + @note Justs cares about the data of connection, reconnecting has to be + done in a derived class. +*/ +void connection::reopen() +{ + if (!is_closed()) + throw std::logic_error("connection::reopen() called with connection still open"); + + closed=false; + + // incomplete buffer data is worthless with a new connection + remove_incomplete_packets(); + + do_callbacks(new_connection); +} }