Пример #1
0
        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();
            }
        }
Пример #2
0
        /// <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);
            }
        }
Пример #3
0
        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
        }
Пример #4
0
        /* 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
            }
        }
Пример #5
0
        /// <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);
            }
        }
Пример #6
0
 public void Send(ReferenceCountedMessage m)
 {
     messagestosend.Enqueue(m);
     sendsignal.Set();
 }
Пример #7
0
 public void Send(ReferenceCountedMessage m)
 {
     emulator.Send(m, this);
 }
Пример #8
0
 public void Send(ReferenceCountedMessage message)
 {
     messagesToSend.Add(message);
 }