--myxa-- #ifndef _SOCKET_PROTOCOL_STACK_ #define

advertisement
--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
Download