⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctpnet.h

📁 用UDP写的可靠传输,非常有借鉴意义,适合互连网通讯
💻 H
📖 第 1 页 / 共 2 页
字号:
// CCTPReceivedData - Buffer for storing received data and information about it
// CCTPErrorInfo - Buffer for storing error information
// CCTPNet - Class, which implements CTP
// Declaration file
//
// (c) Lev Naumov, CAMEL Laboratory
// E-mail: camellab@mail.ru
// For more information see http://camel.ifmo.ru or
// http://www.codeproject.com/internet/ctp.asp
/////////////////////////////////////////////////////////////////////////////

struct CCTPReceivedData {
    // Constructor. Parameters:
    // +) command - command;
    // +) size - amount of data to be stored;
    // +) from - ip address of host, that sends this data;
    // +) buf - points to buffer, which stores received data. If NULL then
    //    data copying will be skipped (only allocation performs)
    CCTPReceivedData(unsigned __int16 command, unsigned __int64 size, unsigned long from, char* buf);
    // Destructor
    virtual ~CCTPReceivedData() {delete[] pBuf;};

    unsigned __int16 command; // Command
    unsigned __int64 size; // Message size (48 bit)
    IPAddr from; // Host, that had sent this data
    char* pBuf; // Data
};

struct CCTPErrorInfo {
    // Constructor. Parameters:
    // +) type - error type. When it occurs:
    //    +) 0 - on socket creation;
    //    +) 1 - on socket binding;
    //    +) 2 - on data sending;
    //    +) 3 - on data receiving;
    //    +) 4 - if sent data was not confirmed too long.
    // +) command - command;
    // +) code - WinSock error code;
    // +) addr - address of host, which causes error (not always can be
    // interpreted, if can not the just equals localhost)
    CCTPErrorInfo(unsigned char type,unsigned __int16 command,int code,IPAddr addr);

    // Put time stamp to string s and returns it
    static char* GetTimeStamp(char* s);

    unsigned char type; // Error type
    unsigned __int16 command; // Command
    int code; // WinSock error code
    IPAddr addr; // Address of host, which causes error
    char timestamp[22]; // Time stamp, when error occurred
};

class CCTPNet: public NetSender
{
public:
    // Data structures

    // Packet header
#pragma pack(push)
#pragma pack(1)
    struct Header {
        // Constructor
        Header() {size=0;command=0;number=0;amount=0;id=0;messize=0;options=0;}

        void ToStream(ostream& out);

        unsigned __int16 size    ; // Packet size (16)
        unsigned __int16 command ; // Command (16)
        unsigned __int32 number  ; // Packet number (from zero to amount-1) (32)
        unsigned __int32 amount  ; // Amount of packets in the command (32)
        unsigned __int32 id      ; // Packet id (32)
        unsigned __int64 messize ; // Message size (64, but 48 are used)
        unsigned __int8  options ; // Options (8)
    };
#pragma pack(pop)

    // Options bits
    enum Options {
        // Delete sent command from the storage after error was
        // generated
        DelAfterError=0x01,

        // Do not resend this packet even if it was not confirmed
        NoResend=0x02,

        // Confirmation of this packets command will confirm all packets with
        // the same command, that was sent to same recipient.
        // NB: It is not recommended to use this option with multipacket
        // messages to protect it from integrity corruption
        UniqueCommand=0x04,

        // Broadcast this message (message with this option will be confirmed
        // from arbitrary recipient)
        Broadcast=0x08,

        // Mark packet, which is first in the session (in the interchange with
        // given recipient)
        // Note: This option is used by CTP internal world and is not needed to
        // be set by user
        StartSession=0x10
    };

    // Set of options, which appropriate for ping
    static const unsigned __int8 OptPing;

    // Structures for messages and error information delivery
    enum DeliveryType {
        ReceivedData,
        ErrorInfo
    };
    struct Delivery {
        // Constructor
        Delivery(NetReceiver* target,CCTPErrorInfo* data) {this->target=target; this->data=data; this->type=DeliveryType::ErrorInfo;};
        Delivery(NetReceiver* target,CCTPReceivedData* data) {this->target=target; this->data=data; this->type=DeliveryType::ReceivedData;};
        Delivery() {target=NULL; data=NULL; type=(DeliveryType)NULL;}; // Only for STL compliance

        NetReceiver* target; // Receiver
        void* data; // Data
        DeliveryType type; // Delivery type
    };
    typedef list<Delivery> DeliveriesList;

    // Time settings storage structure
    struct Times {
        // Constructor, which sets defaults
        Times() {
            uMultiplier=       3;
            uDefTimeout=       100;
            uSleepOnDestroy=   50;
            uSleepSuspended=   10;
            uSleepDelMan=      10;
            uSleepNothing=     20;
            uPeriodDestroy=    2000;
            uPeriodAutoDest=   20000;
            uPeriodCheckResend=100;
        };

        // Multiplier for the time, needed for single transfer, to determine
        // timeout
        unsigned int uMultiplier;

        // Default timeout
        unsigned int uDefTimeout;
    
        // Sleeping time during waiting for desroying
        unsigned int uSleepOnDestroy;

        // Sleeping time when suspended
        unsigned int uSleepSuspended;

        // Sleeping time in deriveries manager
        unsigned int uSleepDelMan;

        // Sleeping time when server has nothing to do
        unsigned int uSleepNothing;

        // Period while waiting for desroying, after which working threads will
        // be stopped forcedly
        unsigned int uPeriodDestroy;

        // If deliverer will do nothing during this period it will be destroyed 
        unsigned int uPeriodAutoDest;

        // Period of checking if some packets are to be resent
        unsigned int uPeriodCheckResend;
    };

    // Constructor creates server with all necessary parameter and tunes client
    // for fast data sending:
    // +) receiver - default receiver of arrived data and errors;
    // +) port - number of port, which to listen;
    // +) servers - amount of setvers to be started;
    // +) times - pointer to time settings storage structure (if NULL then
    //    defaults will be used);
    // +) log - points to output stream for gebug log building (if NULL then no
    //    output will be produced.
    // +) packetdatasize - value of maximum data size to be send in single
    //    packet (if message is bigger than it is the "large message");
    // +) maxthreads - maximum amount of deliverers threads
    CCTPNet(NetReceiver* receiver,unsigned short port,unsigned short servers=1,Times* times=NULL,ostream* log=NULL,unsigned __int16 packetdatasize=65400,unsigned short maxthreads=50);

    // Destructor
    virtual ~CCTPNet();

    // Parameter access routines

    // Time settins routines
    const Times& GetTimes() {return m_Times;}
    void SetTimes(Times& times) {m_Times=times;}

    // Port routines
    unsigned short GetPort() {return m_uPort;}
    void SetPort(unsigned short port) {closesocket(m_SendSocket); closesocket(m_RecvSocket); FreeSntCommands(); FreeSessions(); FreeLargeCommands(); m_uPort=port; CreateSockets();}

    // Packet data size routines
    unsigned __int16 GetPacketDataSize() {return m_uPacketDataSize;}
    void SetPacketDataSize(unsigned __int16 ps) {delete[] m_pBuffer; m_uPacketDataSize=ps; m_pBuffer=new char[m_uPacketDataSize+GetHeaderSize()];}

    // Maximal threads amount routines
    void SetMaxDeliverers(unsigned short maxthreads) {m_uMaxDeliverers=maxthreads;};
    unsigned short GetMaxDeliverers() {return m_uMaxDeliverers;};

    // Info target routines
    NetReceiver* GetDefaultReceiver() {return m_DefReceiver;}
    void SetDefaultReceiver(NetReceiver* receiver) {m_DefReceiver=receiver;}
    // Sets special receiver receiver for command command and type type. If
    // receiver for definite command and delivery type already exists it will
    // be replaced
    void AddSpecialReceiver(unsigned __int16 command, NetReceiver* receiver, DeliveryType type);
    // Delete receiver receiver from special receivers list
    void DeleteSpecialReceiver(NetReceiver* receiver);
    // Returns receiver for command command and type type
    NetReceiver* GetReceiver(unsigned __int16 command, DeliveryType type);

    // Suspending status routines
    bool GetSuspended() {return m_bSuspended;};
    void SetSuspended(bool suspended) {m_bSuspended=suspended;};
    virtual bool IsWorking() {return !m_bSuspended;};

    // Operations

    // Returns size or datagrams header
    static unsigned __int16 GetHeaderSize() {return sizeof(Header);}

    // Send smart buffer sb to address to. Parameter command represents command
    // id. Parameter options - sending options. If parameter storeiffail is
    // true then sent command will be stored in sent packets storage even if
    // sending fails and will not otherwise. Returns true if succeeded (message
    // has gone) and false otherwise
    virtual bool Send(SmartBuffer& sb, unsigned __int16 command, IPAddr to, unsigned __int8 options=0, bool storeiffail=true);

    // Send dataless packet (header only). Parameter command represents command
    // id. Parameter options - sending options. If parameter storeiffail is
    // true then sent command will be stored in sent packets storage even if
    // sending fails and will not otherwise. Returns true if succeeded (message
    // has gone) and false otherwise
    bool Send(unsigned __int16 command, IPAddr to, unsigned __int8 options=0, bool storeiffail=true) {return Send(*(new SmartBuffer()),command,to,options,storeiffail);};

    // Save information about packet received from from with header head.
    // Returns true if new message was received and false otherwise
    bool SaveRcvPacket(unsigned long from,Header* head);

    // Mark packet sent to to with header pointed by header as confirmed.
    // Memory will be cleared if possible
    void ConfirmSntPacket(unsigned long to,Header* header);

    // Send to to confirmation of receipt of the packet with header, pointed by
    // header
    void SendConfirmation(unsigned long to,Header header);

    // Arrange large packet received from from with hearer pointed by head.
    // Function returns true if solid message is arranged after last packet
    bool ArrangeLargeCommand(unsigned long from,Header* head);

    // Resend packets, which have not got confimational commands
    void ResendNotConfirmedData();

    // Determines is command is confirmation of command or not
    inline bool IsConfirmation(unsigned __int16 command) {return (command&m_iConfirm)!=0;};

    // Retrieving status information functions

    // Returns amount of entries in sent commands storage
    inline unsigned int GetSntCommandsCount() {return m_SntCommands.size();};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -