private void Send(ReferenceCountedMessage m, EmulatorQueue from) { if (connected) { BufferedMessage b; b.msg = m; b.timeToRecieveOn = time.gameTime + TimeManager.FromSeconds(latency); Profiler.BeginSample("Enqueue"); foreach (var item in queues) { if (item != from) { m.Acquire(); item.messages.Enqueue(b); } } m.Release(); Profiler.EndSample(); } else { m.Release(); } }
/// <summary> /// This member is the entry point for the send thread. As this connection may wait for a remote to connect, /// send will accept and queue messages until ready.This thread will block until signalled that a connection is /// made, or that there are new messages to transmit. /// </summary> private void SendThreadFunction() { byte[] buildBuffer = new byte[UDP_MAX_DATAGRAM_SIZE]; // working memory for building udp packets int maxPayloadSize = buildBuffer.Length - HEADERSIZE; try { do { sendsignal.WaitOne(); // waits until there is some data to send while (messagestosend.Count > 0) { ReferenceCountedMessage m = (ReferenceCountedMessage)messagestosend.Dequeue(); if (m.length == 0) { m.Release(); continue; // don't send empty messages. } if (m.length > maxPayloadSize) { Debug.LogException(new Exception(string.Format("Message size {0} exceeds the maximum payload size of {1} bytes", m.length, maxPayloadSize))); m.Release(); continue; } Packing.GetBytes(m.length, buildBuffer, 0); Buffer.BlockCopy(m.bytes, m.start, buildBuffer, HEADERSIZE, m.length); int datagramSize = HEADERSIZE + m.length; int sent = socket.Send(buildBuffer, 0, datagramSize, SocketFlags.None); if (sent != datagramSize) { Debug.LogException(new Exception("Socket.Send() sent the wrong number of bytes in UDP mode. This is unexpected.")); } m.Release(); } } while (true); } catch (ThreadInterruptedException) { Debug.Log(def.ToString() + " Send Shutdown."); return; } catch (ObjectDisposedException) { Debug.Log(def.ToString() + " Send Shutdown."); return; } catch (Exception e) { // promote any unhandled exceptions up to Unity via the Debug Log Debug.LogError("Unhandled Exception in " + def.ToString()); Debug.LogException(e); } }
/* This member is the entry point for the send thread. As this connection may wait for a remote to connect, * send will accept and queue messages until ready. This thread will block until signalled that a connection is * made, or that there are new messages to transmit. */ private void SendThreadFunction() { try { // send all the data do { // waits until there is some data to send sendsignal.WaitOne(); while (messagestosend.Count > 0) { ReferenceCountedMessage m = (ReferenceCountedMessage)messagestosend.Dequeue(); if (m == null) { throw new ThreadInterruptedException("Null packet interpreted as signal for thread shutdown."); // exit thread if sent a null payload } SendBytesBlocking(BitConverter.GetBytes(m.length), 0, 4); SendBytesBlocking(m.bytes, m.start, m.length); m.Release(); } } while (true); } catch (ThreadInterruptedException) { } catch (ThreadAbortException) { } catch (ObjectDisposedException) { } catch (Exception e) { Debug.LogException(e); } finally { recvthread.Interrupt(); // if not already interrupted } }