#include <cstring>
#include "communicator.h"
+#include "protocol_impl.h"
+#include "streamsocket.h"
+
+using namespace std;
namespace {
struct Handshake
{
- unsigned hash;
+ Msp::UInt64 hash;
};
class HandshakeReceiver: public PacketReceiver<Handshake>
{
private:
- unsigned hash;
+ Msp::UInt64 hash;
public:
HandshakeReceiver();
- unsigned get_hash() const { return hash; }
+ Msp::UInt64 get_hash() const { return hash; }
virtual void receive(const Handshake &);
};
protocol(p),
receiver(r),
handshake_status(0),
- buf_size(1024),
+ buf_size(65536),
in_buf(new char[buf_size]),
in_begin(in_buf),
in_end(in_buf),
handshake_status = 1;
}
+void Communicator::send_data(size_t size)
+{
+ if(!good)
+ throw sequence_error("connection aborted");
+ if(handshake_status!=2)
+ throw sequence_error("handshake incomplete");
+
+ try
+ {
+ socket.write(out_buf, size);
+ }
+ catch(const std::exception &e)
+ {
+ good = false;
+ if(signal_error.empty())
+ throw;
+ signal_error.emit(e);
+ }
+}
+
void Communicator::data_available()
{
if(!good)
return;
- in_end += socket.read(in_end, in_buf+buf_size-in_end);
try
{
+ in_end += socket.read(in_end, in_buf+buf_size-in_end);
+
bool more = true;
while(more)
{
if(handshake_status==2)
- {
more = receive_packet(protocol, receiver);
- }
else
{
HandshakeProtocol hsproto;
HandshakeReceiver hsrecv;
if((more = receive_packet(hsproto, hsrecv)))
{
+ if(handshake_status==0)
+ send_handshake();
+
if(hsrecv.get_hash()==protocol.get_hash())
{
- if(handshake_status==0)
- send_handshake();
handshake_status = 2;
signal_handshake_done.emit();
}
else
- good = false;
+ throw incompatible_protocol("hash mismatch");
}
}
}
}
- catch(...)
+ catch(const exception &e)
{
good = false;
- throw;
+ if(signal_error.empty())
+ throw;
+ signal_error.emit(e);
}
}
{
char *pkt = in_begin;
in_begin += psz;
- proto.disassemble(recv, pkt, psz);
+ proto.dispatch(recv, pkt, psz);
return true;
}
else
{
if(in_end==in_buf+buf_size)
{
- unsigned used = in_end-in_begin;
+ size_t used = in_end-in_begin;
memmove(in_buf, in_begin, used);
in_begin = in_buf;
in_end = in_begin+used;
shake.hash = protocol.get_hash();
HandshakeProtocol hsproto;
- unsigned size = hsproto.assemble(shake, out_buf, buf_size);
+ size_t size = hsproto.serialize(shake, out_buf, buf_size);
socket.write(out_buf, size);
}