UniSet  2.7.0
UDPPacket.h
1 /*
2  * Copyright (c) 2015 Pavel Vainerman.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as
6  * published by the Free Software Foundation, version 2.1.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Lesser General Lesser Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 // -----------------------------------------------------------------------------
17 #ifndef UDPPacket_H_
18 #define UDPPacket_H_
19 // -----------------------------------------------------------------------------
20 #include <list>
21 #include <limits>
22 #include <ostream>
23 #include "UniSetTypes.h"
24 // --------------------------------------------------------------------------
25 namespace uniset
26 {
27  // -----------------------------------------------------------------------------
28  namespace UniSetUDP
29  {
52  const uint32_t UNETUDP_MAGICNUM = 0x133EF54; // идентификатор протокола
53 
54  struct UDPHeader
55  {
56  UDPHeader() noexcept;
57  uint32_t magic;
58  u_char _be_order; // 1 - BE byte order, 0 - LE byte order
59  size_t num;
60  long nodeID;
61  long procID;
62 
63  size_t dcount;
64  size_t acount;
66  friend std::ostream& operator<<( std::ostream& os, UDPHeader& p );
67  friend std::ostream& operator<<( std::ostream& os, UDPHeader* p );
68  } __attribute__((packed));
69 
70  const size_t MaxPacketNum = std::numeric_limits<size_t>::max();
71 
72  struct UDPAData
73  {
74  UDPAData() noexcept: id(uniset::DefaultObjectId), val(0) {}
75  UDPAData(long id, long val) noexcept: id(id), val(val) {}
76 
77  long id;
78  long val;
79 
80  friend std::ostream& operator<<( std::ostream& os, UDPAData& p );
81  } __attribute__((packed));
82 
83 
84  // Теоретический размер данных в UDP пакете (исключая заголовки) 65507
85  // Фактически желательно не вылезать за размер MTU (обычно 1500) - заголовки = 1432 байта
86  // т.е. надо чтобы sizeof(UDPPacket) < 1432
87  // с другой стороны в текущей реализации
88  // в сеть посылается фактическое количество данных, а не sizeof(UDPPacket).
89 
90  // При текущих настройках sizeof(UDPPacket) = 72679 (!)
91  static const size_t MaxACount = 2000;
92  static const size_t MaxDCount = 5000;
93  static const size_t MaxDDataCount = 1 + MaxDCount / 8 * sizeof(unsigned char);
94 
95  struct UDPPacket
96  {
97  UDPPacket() noexcept: len(0) {}
98 
99  size_t len;
100  uint8_t data[ sizeof(UDPHeader) + MaxDCount * sizeof(long) + MaxDDataCount + MaxACount * sizeof(UDPAData) ];
101  } __attribute__((packed));
102 
103  static const size_t MaxDataLen = sizeof(UDPPacket);
104 
105  struct UDPMessage:
106  public UDPHeader
107  {
108  UDPMessage() noexcept;
109 
110  UDPMessage(UDPMessage&& m) noexcept = default;
111  UDPMessage& operator=(UDPMessage&&) noexcept = default;
112 
113  UDPMessage( const UDPMessage& m ) noexcept = default;
114  UDPMessage& operator=(const UDPMessage&) noexcept = default;
115 
116  explicit UDPMessage( UDPPacket& p ) noexcept;
117  size_t transport_msg( UDPPacket& p ) const noexcept;
118 
119  static size_t getMessage( UDPMessage& m, UDPPacket& p ) noexcept;
120 
121  // \warning в случае переполнения возвращается MaxDCount
122  size_t addDData( long id, bool val ) noexcept;
123 
125  bool setDData( size_t index, bool val ) noexcept;
126 
128  long dID( size_t index ) const noexcept;
129 
131  bool dValue( size_t index ) const noexcept;
132 
133  // функции addAData возвращают индекс, по которому потом можно напрямую писать при помощи setAData(index)
134  // \warning в случае переполнения возвращается MaxACount
135  size_t addAData( const UDPAData& dat ) noexcept;
136  size_t addAData( long id, long val ) noexcept;
137 
139  bool setAData( size_t index, long val ) noexcept;
140 
141  long getDataID( ) const noexcept;
143  inline bool isAFull() const noexcept
144  {
145  return (acount >= MaxACount);
146  }
147  inline bool isDFull() const noexcept
148  {
149  return (dcount >= MaxDCount);
150  }
151 
152  inline bool isFull() const noexcept
153  {
154  return !((dcount < MaxDCount) && (acount < MaxACount));
155  }
156 
157  inline size_t dsize() const noexcept
158  {
159  return dcount;
160  }
161 
162  inline size_t asize() const noexcept
163  {
164  return acount;
165  }
166 
167  // размер итогового пакета в байтах
168  size_t sizeOf() const noexcept;
169 
170  uint16_t getDataCRC() const noexcept;
171 
172  // количество байт в пакете с булевыми переменными...
173  size_t d_byte() const noexcept
174  {
175  return dcount * sizeof(long) + dcount;
176  }
177 
178  UDPAData a_dat[MaxACount];
179  long d_id[MaxDCount];
180  uint8_t d_dat[MaxDDataCount];
182  friend std::ostream& operator<<( std::ostream& os, UDPMessage& p );
183  };
184 
185  uint16_t makeCRC( unsigned char* buf, size_t len ) noexcept;
186  }
187  // --------------------------------------------------------------------------
188 } // end of namespace uniset
189 // -----------------------------------------------------------------------------
190 #endif // UDPPacket_H_
191 // -----------------------------------------------------------------------------
Definition: CommonEventLoop.h:14
Definition: UDPPacket.h:72
const ObjectId DefaultObjectId
Definition: UniSetTypes.h:69
Definition: UDPPacket.h:105
Definition: UDPPacket.h:95
size_t dcount
Definition: UDPPacket.h:63
size_t acount
Definition: UDPPacket.h:64
Definition: UDPPacket.h:54