--- /dev/null
+#ifndef MSP_NET_COMMUNICATOR_H_
+#define MSP_NET_COMMUNICATOR_H_
+
+#include "protocol.h"
+#include "streamsocket.h"
+
+namespace Msp {
+namespace Net {
+
+class sequence_error: public std::logic_error
+{
+public:
+ sequence_error(const std::string &w): std::logic_error(w) { }
+ virtual ~sequence_error() throw() { }
+};
+
+
+class Communicator
+{
+public:
+ sigc::signal<void> signal_handshake_done;
+
+private:
+ StreamSocket &socket;
+ const Protocol &protocol;
+ ReceiverBase &receiver;
+ int handshake_status;
+ unsigned buf_size;
+ char *in_buf;
+ char *in_begin;
+ char *in_end;
+ char *out_buf;
+ bool good;
+
+public:
+ Communicator(StreamSocket &, const Protocol &, ReceiverBase &);
+ ~Communicator();
+
+ void initiate_handshake();
+ bool is_handshake_done() const { return handshake_status==2; }
+
+ template<typename P>
+ void send(const P &pkt)
+ {
+ if(!good)
+ throw sequence_error("connection aborted");
+ if(handshake_status!=2)
+ throw sequence_error("handshaking not done");
+ unsigned size = protocol.assemble(pkt, out_buf, buf_size);
+ socket.write(out_buf, size);
+ }
+
+private:
+ void data_available();
+ bool receive_packet(const Protocol &, ReceiverBase &);
+ void send_handshake();
+};
+
+} // namespace Net
+} // namespace Msp
+
+#endif