From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_net_peer_8cpp_source.html | 558 ++++++++++++++++++++++++++++ 1 file changed, 558 insertions(+) create mode 100644 Doc/doxygen/html/_net_peer_8cpp_source.html (limited to 'Doc/doxygen/html/_net_peer_8cpp_source.html') diff --git a/Doc/doxygen/html/_net_peer_8cpp_source.html b/Doc/doxygen/html/_net_peer_8cpp_source.html new file mode 100644 index 0000000..a1cff2b --- /dev/null +++ b/Doc/doxygen/html/_net_peer_8cpp_source.html @@ -0,0 +1,558 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/NetEx/NetPeer.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
NetPeer.cpp
+
+
+Go to the documentation of this file.
1 /* Project nGenEx
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2004. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: NetEx.lib
+
6  FILE: NetPeer.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  One side of a UDP net link connection
+
13 */
+
14 
+
15 
+
16 #include "MemDebug.h"
+
17 #include <windows.h>
+
18 #include "NetPeer.h"
+
19 #include "NetGram.h"
+
20 #include "NetMsg.h"
+
21 #include "NetLayer.h"
+
22 
+
23 #include <stdio.h>
+
24 
+
25 // +-------------------------------------------------------------------+
+
26 
+
27 const int MULTIPART_CHUNKSIZE = 232;
+
28 const int MULTIPART_HEADER = 16;
+
29 const int UDP_HEADER_SIZE = 34;
+
30 
+
31 static NetMsgMultipart multi_part_buffer;
+
32 static DWORD multi_msg_sequence = 1;
+
33 
+
34 // +-------------------------------------------------------------------+
+
35 
+
36 NetPeer::NetPeer(const NetAddr& a, DWORD id)
+
37  : addr(a), netid(id), sequence(0), pps(0), bps(0), max_qsize(0),
+
38  status(OK), hist_indx(0), send_size(0), recv_size(0),
+
39  chunk_size(MULTIPART_CHUNKSIZE)
+
40 {
+
41  ZeroMemory(hist_time, sizeof(hist_time));
+
42  ZeroMemory(hist_size, sizeof(hist_size));
+
43 
+
44  last_recv_time = NetLayer::GetUTC();
+
45 }
+
46 
+ +
48 {
+
49  send_list.destroy();
+
50  recv_list.destroy();
+
51 
+
52  multi_send_list.destroy();
+
53  multi_recv_list.destroy();
+
54 }
+
55 
+
56 // +-------------------------------------------------------------------+
+
57 
+
58 bool
+ +
60 {
+
61  if (msg) {
+
62  if (max_qsize > 0 && msg->Length() + send_size > max_qsize) {
+
63  status = SEND_OVERFLOW;
+
64  delete msg;
+
65  return false;
+
66  }
+
67 
+
68  // simple message
+
69  if (msg->Length() <= (int) chunk_size) {
+
70  if (msg->IsPriority())
+
71  send_list.insert(msg);
+
72  else
+
73  send_list.append(msg);
+
74 
+
75  send_size += msg->Length();
+
76  }
+
77 
+
78  // multipart message
+
79  else {
+
80  List<NetMsg>* list = &send_list;
+
81 
+
82  if (msg->IsScatter())
+
83  list = &multi_send_list;
+
84 
+
85  DWORD nparts = msg->Length() / chunk_size;
+
86  DWORD extra = msg->Length() % chunk_size;
+
87 
+
88  if (extra > 0) nparts++;
+
89 
+
90  multi_part_buffer.type = NetMsg::MULTIPART;
+
91  multi_part_buffer.msgid = multi_msg_sequence++;
+
92  multi_part_buffer.nparts = nparts;
+
93 
+
94  DWORD header_size = (DWORD) (&multi_part_buffer.payload) -
+
95  (DWORD) (&multi_part_buffer);
+
96 
+
97  const BYTE* p = msg->Data();
+
98 
+
99  for (DWORD i = 0; i < nparts; i++) {
+
100  multi_part_buffer.partno = i;
+
101  NetMsg* part = 0;
+
102  DWORD part_size = chunk_size;
+
103 
+
104  if (i == nparts-1 && extra > 0) // last partial payload
+
105  part_size = extra;
+
106 
+
107  CopyMemory(multi_part_buffer.payload, p, part_size);
+
108  p += part_size;
+
109  part = new(__FILE__,__LINE__) NetMsg(msg->NetID(),
+
110  &multi_part_buffer,
+
111  header_size + part_size,
+
112  msg->Flags());
+
113 
+
114  if (part) {
+
115  list->append(part);
+
116  send_size += part->Length();
+
117  }
+
118  }
+
119  }
+
120 
+
121  return true;
+
122  }
+
123 
+
124  return false;
+
125 }
+
126 
+
127 // +-------------------------------------------------------------------+
+
128 
+
129 NetMsg*
+ +
131 {
+
132  if (recv_list.size() > 0) {
+
133  NetMsg* msg = recv_list.removeIndex(0);
+
134  recv_size -= msg->Length();
+
135  return msg;
+
136  }
+
137 
+
138  return 0;
+
139 }
+
140 
+
141 // +-------------------------------------------------------------------+
+
142 
+
143 NetGram*
+ +
145 {
+
146  NetGram* g = 0;
+
147 
+
148  if ((send_list.size() || multi_send_list.size()) && OKtoSend()) {
+
149  AutoThreadSync auto_sync(sync);
+
150 
+
151  int xmit_size = send_size;
+
152  int nmsg = send_list.size();
+
153  int limit = NET_GRAM_MAX_SIZE;
+
154  bool reliable = false;
+
155  bool is_multi = false;
+
156 
+
157  NetMsg* multi_msg = 0;
+
158  List<NetMsg>* list = &send_list;
+
159 
+
160  if (xmit_size > limit) {
+
161  xmit_size = 0;
+
162  nmsg = 0;
+
163 
+
164  if (send_list.size() > 0) {
+
165  NetMsg* msg = 0;
+
166 
+
167  // if there is regular traffic, and multipart traffic
+
168  if (multi_send_list.size()) {
+
169  // just send one multipart message in this packet
+
170  multi_msg = multi_send_list.removeIndex(0);
+
171  limit -= msg->Length();
+
172  reliable = true;
+
173  is_multi = true;
+
174  }
+
175 
+
176  for (int i = 0; i < send_list.size(); i++) {
+
177  NetMsg* msg = send_list[i];
+
178 
+
179  if (xmit_size + msg->Length() < limit) {
+
180  xmit_size += msg->Length();
+
181  nmsg++;
+
182  }
+
183  else {
+
184  break;
+
185  }
+
186  }
+
187  }
+
188  else {
+
189  // if there is only multipart traffic,
+
190  // send as many multipart messages as will fit:
+
191  list = &multi_send_list;
+
192  reliable = true;
+
193  is_multi = true;
+
194 
+
195  for (int i = 0; i < multi_send_list.size(); i++) {
+
196  NetMsg* msg = multi_send_list[i];
+
197 
+
198  if (xmit_size + msg->Length() < limit) {
+
199  xmit_size += msg->Length();
+
200  nmsg++;
+
201  }
+
202  else {
+
203  break;
+
204  }
+
205  }
+
206  }
+
207  }
+
208 
+
209  if (xmit_size > 0 && nmsg > 0) {
+
210  BYTE* buffer = new(__FILE__,__LINE__) BYTE[xmit_size];
+
211  BYTE* p = buffer;
+
212 
+
213  if (multi_msg) {
+
214  if (buffer) {
+
215  CopyMemory(p, multi_msg->Data(), multi_msg->Length());
+
216  p[1] = multi_msg->Length();
+
217  p += multi_msg->Length();
+
218  }
+
219  delete multi_msg;
+
220  }
+
221 
+
222  while (nmsg-- && p < buffer + xmit_size) {
+
223  NetMsg* msg = list->removeIndex(0);
+
224 
+
225  if (msg) {
+
226  if (msg->IsReliable()) reliable = true;
+
227  if (buffer) {
+
228  CopyMemory(p, msg->Data(), msg->Length());
+
229  p[1] = msg->Length();
+
230  p += msg->Length();
+
231  }
+
232  delete msg;
+
233  }
+
234  }
+
235 
+
236  if (buffer) {
+
237  Text user_data((const char*) buffer, xmit_size);
+
238  int retries = 0;
+
239 
+
240  if (reliable)
+
241  retries = 5;
+
242 
+
243  if (is_multi)
+
244  retries = 10;
+
245 
+
246  send_size -= xmit_size;
+
247 
+
248  hist_size[hist_indx] = xmit_size + UDP_HEADER_SIZE;
+
249  hist_time[hist_indx] = NetLayer::GetTime();
+
250  hist_indx++;
+
251 
+
252  if (hist_indx >= HIST_SIZE)
+
253  hist_indx = 0;
+
254 
+
255  g = new(__FILE__,__LINE__) NetGram(addr, user_data, retries);
+
256  delete[] buffer;
+
257  }
+
258  }
+
259 
+
260  // the next msg is too big to fit in a single packet
+
261  else {
+
262  NetMsg* m = send_list.removeIndex(0);
+
263  send_size -= m->Length();
+
264  delete m;
+
265  }
+
266  }
+
267 
+
268  return g;
+
269 }
+
270 
+
271 // +-------------------------------------------------------------------+
+
272 
+
273 bool
+ +
275 {
+
276  if (g) {
+
277  if (max_qsize > 0 && recv_size + g->Size() > max_qsize) {
+
278  status = RECV_OVERFLOW;
+
279  delete g;
+
280  return false;
+
281  }
+
282 
+
283  sequence = g->Sequence();
+
284  recv_size += g->Size() - NET_GRAM_HEADER_SIZE;
+
285 
+
286  // PARSE THE BLOCKS:
+
287  BYTE* p = g->UserData();
+
288 
+
289  while (p < g->Data() + g->Size()) {
+
290  BYTE block_type = p[0];
+
291  BYTE block_size = p[1];
+
292 
+
293  if (!block_type || !block_size)
+
294  break;
+
295 
+
296  NetMsg* msg = new(__FILE__,__LINE__) NetMsg(netid, p, block_size);
+
297 
+
298  if (msg) {
+
299  if (msg->Type() < NetMsg::RESERVED) {
+
300  msg->SetSequence(sequence);
+
301 
+
302  recv_list.insertSort(msg);
+
303 
+
304  if (q)
+
305  q->insertSort(msg);
+
306 
+
307  p += block_size;
+
308  }
+
309 
+
310  else if (msg->Type() == NetMsg::MULTIPART) {
+
311  multi_recv_list.insertSort(msg);
+
312  p += block_size;
+
313 
+
314  CheckMultiRecv(q);
+
315  }
+
316  }
+
317  }
+
318 
+
319  last_recv_time = NetLayer::GetUTC();
+
320 
+
321  delete g;
+
322  return true;
+
323  }
+
324 
+
325  return false;
+
326 }
+
327 
+
328 // +-------------------------------------------------------------------+
+
329 
+
330 bool
+
331 NetPeer::OKtoSend() const
+
332 {
+
333  if (pps || bps) {
+
334  DWORD hist_total = 0;
+
335  DWORD hist_count = 0;
+
336  DWORD now = NetLayer::GetTime();
+
337  DWORD hist_oldest = now;
+
338  DWORD hist_newest = 0;
+
339 
+
340  for (int i = 0; i < HIST_SIZE; i++) {
+
341  if (hist_size[i] > 0) {
+
342  hist_total += hist_size[i];
+
343  hist_count++;
+
344  }
+
345 
+
346  if (hist_time[i] > 0) {
+
347  if (hist_time[i] < hist_oldest)
+
348  hist_oldest = hist_time[i];
+
349 
+
350  if (hist_time[i] > hist_newest)
+
351  hist_newest = hist_time[i];
+
352  }
+
353  }
+
354 
+
355  if (now - hist_newest < (DWORD) pps)
+
356  return false;
+
357 
+
358  DWORD delta = now - hist_oldest;
+
359  DWORD avg_bps = hist_total / delta;
+
360 
+
361  if (bps > 0 && avg_bps > (DWORD) bps)
+
362  return false;
+
363  }
+
364 
+
365  return true;
+
366 }
+
367 
+
368 // +-------------------------------------------------------------------+
+
369 
+ +
371  DWORD msgid;
+
372  DWORD netid;
+
373  int nreq;
+
374  int nparts;
+
375  int nbytes;
+
376 };
+
377 
+
378 void
+
379 NetPeer::CheckMultiRecv(List<NetMsg>* q)
+
380 {
+
381  const int MAX_SIMULTANEOUS_MULTI_SEQUENCES = 8;
+
382 
+
383  PacketAssembly assy[MAX_SIMULTANEOUS_MULTI_SEQUENCES];
+
384  ZeroMemory(assy, sizeof(assy));
+
385 
+
386  DWORD header_size = (DWORD) (&multi_part_buffer.payload) -
+
387  (DWORD) (&multi_part_buffer);
+
388 
+
389  // Catalog how much of each multipart sequence has been received:
+
390  for (int i = 0; i < multi_recv_list.size(); i++) {
+
391  NetMsg* msg = multi_recv_list[i];
+
392  NetMsgMultipart* m = (NetMsgMultipart*) msg->Data();
+
393 
+
394  for (int n = 0; n < MAX_SIMULTANEOUS_MULTI_SEQUENCES; n++) {
+
395  PacketAssembly* a = assy + n;
+
396 
+
397  if (a->msgid == 0 || (a->msgid == m->msgid && a->netid == msg->NetID())) {
+
398  a->msgid = m->msgid;
+
399  a->netid = msg->NetID();
+
400  a->nreq = m->nparts;
+
401  a->nparts += 1;
+
402  a->nbytes += m->len - header_size;
+
403  break;
+
404  }
+
405  }
+
406  }
+
407 
+
408  for (int n = 0; n < MAX_SIMULTANEOUS_MULTI_SEQUENCES; n++) {
+
409  PacketAssembly* a = assy + n;
+
410 
+
411  // is this sequence complete?
+
412  if (a->msgid && a->nparts == a->nreq) {
+
413  BYTE* buffer = new BYTE[a->nbytes];
+
414  BYTE* p = buffer;
+
415  WORD nid = 0;
+
416 
+
417  ListIter<NetMsg> iter = multi_recv_list;
+
418  while (++iter) {
+
419  netid = iter->NetID();
+
420  NetMsgMultipart* m = (NetMsgMultipart*) iter->Data();
+
421 
+
422  // found part of the sequence
+
423  if (m->msgid == a->msgid && netid == a->netid) {
+
424  // copy it into the buffer
+
425  CopyMemory(p, m->payload, m->len - header_size);
+
426  p += m->len - header_size;
+
427 
+
428  delete iter.removeItem();
+
429  }
+
430  }
+
431 
+
432  NetMsg* msg = new(__FILE__,__LINE__) NetMsg(netid, buffer, a->nbytes, NetMsg::RELIABLE);
+
433  if (msg) {
+
434  recv_list.insertSort(msg);
+
435 
+
436  if (q)
+
437  q->insertSort(msg);
+
438  }
+
439  }
+
440  }
+
441 }
+
+
+ + + + -- cgit v1.1