/// <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); }
/// <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; } }