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); } }
private void Return(ReferenceCountedMessage message) { // note the order of returns! bool clear = false; #if DEBUG clear = true; #endif pool.Return(message.bytes, clear); message.bytes = null; message.length = 0; bag.Add(message as MessagePoolMessage); // private method will only ever be called from within MessagePoolMessage }
/* 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 } }
/// <summary> /// This member is the entry point for the receive thread. This thread creates (or waits for) the connection /// to the remote counterpart, and then continually recieves complete messages into inbox until the socket /// is closed.The correct way to terminate this thread is to close the socket, which will end any waiting. /// </summary> private void ReceiveThreadFunction() { byte[] buffer = new byte[UDP_MAX_DATAGRAM_SIZE]; // working memory for receiving udp packets. this is the max size according to udp. our max size may be smaller. // make sure this block surrounds the entire function, as otherwise exceptions may disappear. try { ConnectWithRemoteEndpoint(); // ready to start sending sendthread.Start(); while (true) { /* * If you are using a connectionless Socket, Receive will read the first queued datagram from the * destination address you specify in the Connect method. If the datagram you receive is larger * than the size of the buffer parameter, buffer gets filled with the first part of the message, * the excess data is lost and a SocketException is thrown. * https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.receive?view=netframework-4.8 */ int receieved = socket.Receive(buffer); if (receieved == 0) { break; // the socket has been gracefully closed. } if (receieved < HEADERSIZE) { throw new IncompleteMessageException(); } int size = Packing.GetInt(buffer, 0); if (size != receieved - HEADERSIZE) { throw new IncompleteMessageException(); } ReferenceCountedMessage m = pool.Rent(size); Buffer.BlockCopy(buffer, HEADERSIZE, m.bytes, m.start, size); messagesreceived.Enqueue(m); } } catch (ObjectDisposedException) { Debug.Log(def.ToString() + " Receive Shutdown."); } catch (SocketException e) { switch (e.ErrorCode) { case WSAEINTR: Debug.Log(def.ToString() + " Receive Shutdown"); return; default: Debug.LogException(e); return; } } catch (Exception e) { Debug.LogException(e); } }
public void Send(ReferenceCountedMessage m) { messagestosend.Enqueue(m); sendsignal.Set(); }
public void Send(ReferenceCountedMessage m) { emulator.Send(m, this); }
public void Send(ReferenceCountedMessage message) { messagesToSend.Add(message); }