|
UniSet
2.6.0
|
00001 /* 00002 * Copyright (c) 2015 Pavel Vainerman. 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU Lesser General Public License as 00006 * published by the Free Software Foundation, version 2.1. 00007 * 00008 * This program is distributed in the hope that it will be useful, but 00009 * WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 * Lesser General Lesser Public License for more details. 00012 * 00013 * You should have received a copy of the GNU Lesser General Public License 00014 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00015 */ 00016 // ----------------------------------------------------------------------------- 00017 #ifndef UDPPacket_H_ 00018 #define UDPPacket_H_ 00019 // ----------------------------------------------------------------------------- 00020 #include <list> 00021 #include <limits> 00022 #include <ostream> 00023 #include "UniSetTypes.h" 00024 // -------------------------------------------------------------------------- 00025 namespace uniset 00026 { 00027 // ----------------------------------------------------------------------------- 00028 namespace UniSetUDP 00029 { 00043 const uint32_t UNETUDP_MAGICNUM = 0x1337A1D; // идентификатор протокола 00044 00045 struct UDPHeader 00046 { 00047 UDPHeader() noexcept: magic(UNETUDP_MAGICNUM), num(0), nodeID(0), procID(0), dcount(0), acount(0) {} 00048 uint32_t magic; 00049 size_t num; 00050 long nodeID; 00051 long procID; 00052 00053 size_t dcount; 00054 size_t acount; 00056 friend std::ostream& operator<<( std::ostream& os, UDPHeader& p ); 00057 friend std::ostream& operator<<( std::ostream& os, UDPHeader* p ); 00058 } __attribute__((packed)); 00059 00060 const size_t MaxPacketNum = std::numeric_limits<size_t>::max(); 00061 00062 struct UDPAData 00063 { 00064 UDPAData() noexcept: id(uniset::DefaultObjectId), val(0) {} 00065 UDPAData(long id, long val) noexcept: id(id), val(val) {} 00066 00067 long id; 00068 long val; 00069 00070 friend std::ostream& operator<<( std::ostream& os, UDPAData& p ); 00071 } __attribute__((packed)); 00072 00073 00074 // Теоретический размер данных в UDP пакете (исключая заголовки) 65507 00075 // Фактически желательно не вылезать за размер MTU (обычно 1500) - заголовки = 1432 байта 00076 // т.е. надо чтобы sizeof(UDPPacket) < 1432 00077 00078 // При текущих настройках sizeof(UDPPacket) = 32654 (!) 00079 static const size_t MaxACount = 1500; 00080 static const size_t MaxDCount = 5000; 00081 static const size_t MaxDDataCount = 1 + MaxDCount / 8 * sizeof(unsigned char); 00082 00083 struct UDPPacket 00084 { 00085 UDPPacket() noexcept: len(0) {} 00086 00087 size_t len; 00088 uint8_t data[ sizeof(UDPHeader) + MaxDCount * sizeof(long) + MaxDDataCount + MaxACount * sizeof(UDPAData) ]; 00089 } __attribute__((packed)); 00090 00091 static const size_t MaxDataLen = sizeof(UDPPacket); 00092 00093 struct UDPMessage: 00094 public UDPHeader 00095 { 00096 UDPMessage() noexcept; 00097 00098 UDPMessage(UDPMessage&& m) noexcept = default; 00099 UDPMessage& operator=(UDPMessage&&) noexcept = default; 00100 00101 UDPMessage( const UDPMessage& m ) noexcept = default; 00102 UDPMessage& operator=(const UDPMessage&) noexcept = default; 00103 00104 explicit UDPMessage( UDPPacket& p ) noexcept; 00105 size_t transport_msg( UDPPacket& p ) const noexcept; 00106 00107 static size_t getMessage( UDPMessage& m, UDPPacket& p ) noexcept; 00108 00109 // \warning в случае переполнения возвращается MaxDCount 00110 size_t addDData( long id, bool val ) noexcept; 00111 00113 bool setDData( size_t index, bool val ) noexcept; 00114 00116 long dID( size_t index ) const noexcept; 00117 00119 bool dValue( size_t index ) const noexcept; 00120 00121 // функции addAData возвращают индекс, по которому потом можно напрямую писать при помощи setAData(index) 00122 // \warning в случае переполнения возвращается MaxACount 00123 size_t addAData( const UDPAData& dat ) noexcept; 00124 size_t addAData( long id, long val ) noexcept; 00125 00127 bool setAData( size_t index, long val ) noexcept; 00128 00129 long getDataID( ) const noexcept; 00131 inline bool isAFull() const noexcept 00132 { 00133 return (acount >= MaxACount); 00134 } 00135 inline bool isDFull() const noexcept 00136 { 00137 return (dcount >= MaxDCount); 00138 } 00139 00140 inline bool isFull() const noexcept 00141 { 00142 return !((dcount < MaxDCount) && (acount < MaxACount)); 00143 } 00144 00145 inline size_t dsize() const noexcept 00146 { 00147 return dcount; 00148 } 00149 00150 inline size_t asize() const noexcept 00151 { 00152 return acount; 00153 } 00154 00155 // размер итогового пакета в байтах 00156 size_t sizeOf() const noexcept; 00157 00158 uint16_t getDataCRC() const noexcept; 00159 00160 // количество байт в пакете с булевыми переменными... 00161 size_t d_byte() const noexcept 00162 { 00163 return dcount * sizeof(long) + dcount; 00164 } 00165 00166 UDPAData a_dat[MaxACount]; 00167 long d_id[MaxDCount]; 00168 uint8_t d_dat[MaxDDataCount]; 00170 friend std::ostream& operator<<( std::ostream& os, UDPMessage& p ); 00171 }; 00172 00173 uint16_t makeCRC( unsigned char* buf, size_t len ) noexcept; 00174 } 00175 // -------------------------------------------------------------------------- 00176 } // end of namespace uniset 00177 // ----------------------------------------------------------------------------- 00178 #endif // UDPPacket_H_ 00179 // -----------------------------------------------------------------------------
1.7.6.1