예제 #1
0
        /// <summary>
        /// Send the specified udp message. This assumes the stream was written
        /// </summary>
        public void Send(UdpMessage message, TransportOptions options = null, IAction onSent = null)
        {
            // is disposed?
            if (_disposed)
            {
                Log.Warning("Cannot send from disposed connection.");
                return;
            }

            // reset the timeout
            if (_timeoutTimer != null)
            {
                _timeoutTimer.Reset(_timeoutMilliseconds);
            }

            // reset the message stream position
            message.Buffer.Position = 0;

            // start sending the message stream
            StartSendStream(message.Buffer.Stream, (int)message.Buffer.WriteEnd, options, onSent);
        }
예제 #2
0
        /// <summary>
        /// On data being received by the local end point.
        /// </summary>
        internal void OnReceived(IPEndPoint endpoint, byte[] bytes, int count)
        {
            // should the client receive?
            if (_disposed)
            {
                // no, cache the buffer
                BufferCache.Set(bytes);
                // skip
                return;
            }

            // should the endpoint be received from?
            if (RemoteEndPoint.Port != endpoint.Port || !RemoteEndPoint.Address.Equals(endpoint.Address))
            {
                // no, cache the buffer
                BufferCache.Set(bytes);

                // log a warning
                Log.Warning("Connection " + this + " received from incorrect endoint '" + endpoint + "'.");

                return;
            }

            // reset the timeout
            if (_timeoutTimer != null)
            {
                _timeoutTimer.Reset(_timeoutMilliseconds);
            }

            int index = 0;

            _lock.Take();

            try {
                // while the bytes received haven't been completely parsed
                while (count != 0)
                {
                    // try passing the received bytes to the current request
                    int added = _message.TryAdd(bytes, index, count);

                    // has the request been completed?
                    if (_message.Complete)
                    {
                        // has the callback on requests been specified?
                        if (_onMessage.Action == null)
                        {
                            // no, add to the backlog collection
                            _messages.Add(_message);
                        }
                        else
                        {
                            // yes, run the callback
                            _onMessage.Run(_message);
                        }

                        // construct a new message to receive bytes
                        _message = new UdpMessage(this);
                    }
                    else if (added == -1)
                    {
                        _lock.Release();

                        // no, there was an error, possibly with the format of the request
                        // callback with the error
                        ProcessError(new Exception(_message.ErrorMessage));

                        // re-allocate the buffer
                        BufferCache.Set(bytes);

                        return;
                    }

                    // increment the index
                    index += added;
                    // decrement the number of bytes received that are still to be processed
                    count -= added;
                }

                _lock.Release();
            } catch (Exception ex) {
                // replace a potentially corrupt message
                _message.Dispose();
                _message = new UdpMessage(this);

                _lock.Release();

                Log.Error("Exception processing message.", ex);

                // process the exception
                ProcessError(ex);

                return;
            }
        }