--myxa-#ifndef _SOCKET_PROTOCOL_STACK_ #define _SOCKET_PROTOCOL_STACK_ #include "osocklib.h" #include "../common/packet.h" #include "../common/cthreads.h" namespace BAM { using namespace std;// это чтобы можно было работать чисто с строками а не писать std::string и т.п. // это static static static static static static static просто какие ошибки могут быть const SocketException EXC_BadPacket("Invalid Packet"); const SocketException EXC_BadOperation("Invalid operation with socket"); const SocketException EXC_Login("No such login"); const SocketException EXC_Auth("Authorization failed"); const SocketException EXC_Field("Invalid field value"); const SocketException EXC_QEmpty("Queue is empty"); const SocketException EXC_Sequence("Assembling routine is broken"); static const SocketException EXC_Unsupported("Method unsupported"); // controller следит за потоком и вызывает свои методы в зависимости от того что есть в потоке class iPacketController { public: virtual void onConnect(const cIPAddr &Addr) = 0;// вызывает соединение по указанному ip virtual void onDisconnect() = 0;// вызывает разрыв соединения -//virtual void onInit(const cIPAddr &Addr) = 0;// вызывает инициализацию -//virtual void onSend(const cPacket &P) = 0;// отправка virtual void onRecv(const cPacket &P) = 0;// принятие virtual bool haveOutcome() const = 0;// проверка есть ли исходящие virtual bool haveIncome() const = 0;// проверка есть ли входящие virtual bool isInited() const = 0;// проверка инициализован или нет virtual bool isFinished() const = 0;// проверка закончено или нет virtual Sock_State state(Sock_State TransportState) const = 0; // состояние сокета в osock.lib описаны какие бывают virtual cPacket outcome() = 0;// virtual cPacket income() = 0;// virtual iPacketController* clone() const = 0;// создаёт копию virtual ~iPacketController(){}; }; // как я понял это сокеты самого iPacket контроллера class cPSocket : public iSocket { protected: iSocket *vSock; iPacketController *vPControl; public: cPSocket(iPacketController *PControler, iSocket *Transport=0);// сокет определённого controllerа и где Transport это то по чему и будет идти обмен (путь короче) ~cPSocket(); void shortinit(SOCKET S, const cIPAddr &Addr);//тоже что init() только для указанного сокета и ip(также устанавливает контроллер vPControl на onInit) void shortinit(iSocket* s);//shortinit только для указателя на сокет void setTransport(iSocket* transport);// устанавливает вид transportа iSocket* getTransport();// возвращает вид пути void init();// инитит vSockи проверяет контроллер на входящие исходящие а также проверяет статус vSocketa : если нет соединения и не соединён то зачемто обрывают соединение vSocketa void connect(const cIPAddr &Addr);// connectит по указаному ip void disconnect();// рассоединяет cPacket recv();// принимает пакет void send(const cPacket &P);// отправляет пакет Sock_State state() const // возвращает состояние vSockета { return vPControl->state(vSock->state()); } const cIPAddr& getAddr() const //возвращает ip vSockета { return vSock->getAddr(); } bool isReadable(); //true если можно сокет прочитать bool isWriteable(); //true если можно что либо записать bool isAcceptable() //тоже что и в обычном winsoke например тока у этого сокета всегда False. Говорят потому что этот сокет не принисает соединений { return false; } SOCKET descriptor() //дескриптор. Возвращает дескриптор vSockета { return vSock->descriptor(); } iSocket* clone() const; }; // ему дается cPocket и все поля из него могут быть взяты (как бинарные так и intы) class iPacketWrapper { public: virtual ~iPacketWrapper() {} virtual qword getIntField(dword Index) const = 0;// вернёт поле указанное по Indexу типа int и запишет в виде dword virtual void setIntField(dword Index, qword Val) = 0;// установит поле virtual dword getIntFieldCount() const = 0;// вернёт число полей // тоже самое толька для бинарных virtual cPacket getBinField(dword Index) const = 0; virtual dword getBinFieldLength(dword Index) const = 0;// вернёт длину указанного в Index поля virtual void setBinField(dword Index, const cPacket &P) = 0; virtual dword getBinFieldCount() const = 0; virtual dword getHeaderLength() const = 0;// вернёт длину заголовка virtual dword getFullLength(const cPacket &P) const = 0;// всю длину поля данных virtual dword getMaxLength() const = 0;// кажеться что вернёт вообще всю длину cPacketa virtual cPacket compile() = 0;//”переделывает” из cPacket в cPacketWrapper при том если тока cPacket нормально получен virtual iPacketWrapper* decompile(const cPacket &P) = 0;// наоборот //I assume it allocates memory in heap; call `delete' to free it }; // контроллер для создания пакетов iPacketWrapper class cAssemblerController : virtual public iPacketController { private: word vFullLength; cPacket vBuffer;// буфер пакета (то что отправляется) iPacketWrapper* vWrapper; bool vRunning;// true если что то отправляется( наверное если буфер не пуст ) protected: void setWrapper(iPacketWrapper* s);// устанавливает Wrapper для указателя s на пакет iPacketWrapper virtual void received(const iPacketWrapper &P) = 0;// проверка получено ли что нибудь public: cAssemblerController(iPacketWrapper* wr); virtual ~cAssemblerController(); void onRecv(const cPacket &P);// устанавливает контроллер на получение пакетов void reset();//очищает буфер и устанавливает vRunning на false }; // контроллер похожий на AssemblerController но работает со своим сокетом ActiveSocket в котором лежит метод onIdle ( запускает этот самый Idle не понятно тока что это за Idle и чё он делает) а также есть Timer по которому и запускается Idle. class cActiveController : virtual public iPacketController { protected: cPSocket* vOwner; public: cActiveController(); ~cActiveController(); void setOwner(cPSocket* owner); virtual void onIdle(Sock_State TransportState) = 0; }; static const dword Idle_Time_Ms = 15000;// время скока ждёт метод Idle // это и есть тот сокет с которым работает ActiveController class cActiveSocket : public cPSocket { protected: // здесьуказаны задачи для ActiveControllera class cSocketJob : public iRunnable { private: cActiveSocket* vSocket; public: cSocketJob(cActiveSocket* ctrl); // описано в chreads void run(); void stop(); }; mutable cRecursiveMutex vActiveLock; cTimer* vTimer;// как раз этот самый Timer по которому осуществляеться запуск метода onIdle cSocketJob* vJob; public: cActiveSocket(cActiveController* control, iSocket* transport = 0); ~cActiveSocket(); // те же методы что и для всех других сокетов тока добавлен метод Idle void idle(); void shortinit(SOCKET S, const cIPAddr &Addr); void shortinit(iSocket* s); void setTransport(iSocket* transport); iSocket* getTransport(); void init(); void connect(const cIPAddr &Addr); void disconnect(); cPacket recv(); void send(const cPacket &P); Sock_State state() const; const cIPAddr& getAddr() const; bool isReadable(); bool isWriteable(); bool isAcceptable(); SOCKET descriptor(); iSocket* clone() const; }; } #endif