Beispiel #1
0
        private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding, CancellationToken cancellationToken)
        {
            var parts = messageText.Split('|');

            var localUrl = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false);

            if (!string.IsNullOrEmpty(localUrl))
            {
                var response = new ServerDiscoveryInfo
                {
                    Address = localUrl,
                    Id      = _appHost.SystemId,
                    Name    = _appHost.FriendlyName
                };

                await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint, cancellationToken).ConfigureAwait(false);

                if (parts.Length > 1)
                {
                    _appHost.EnableLoopback(parts[1]);
                }
            }
            else
            {
                _logger.LogWarning("Unable to respond to udp request because the local ip address could not be determined.");
            }
        }
Beispiel #2
0
        private void CreateSocket()
        {
            try
            {
                sock = _socketFactory.CreateSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode);
            }
            catch (SocketCreateException ex)
            {
                if (_enableDualMode && endpoint.IpAddress.Equals(IpAddressInfo.IPv6Any) &&
                    (string.Equals(ex.ErrorCode, "AddressFamilyNotSupported", StringComparison.OrdinalIgnoreCase) ||
                     // mono on bsd is throwing this
                     string.Equals(ex.ErrorCode, "ProtocolNotSupported", StringComparison.OrdinalIgnoreCase)))
                {
                    endpoint        = new IpEndPointInfo(IpAddressInfo.Any, endpoint.Port);
                    _enableDualMode = false;
                    sock            = _socketFactory.CreateSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode);
                }
                else
                {
                    throw;
                }
            }

            sock.Bind(endpoint);

            // This is the number TcpListener uses.
            sock.Listen(2147483647);

            sock.StartAccept(ProcessAccept, () => _closed);
            _closed = false;
        }
Beispiel #3
0
        private List <ISocket> GetSendSockets(IpAddressInfo fromLocalIpAddress, IpEndPointInfo destination)
        {
            EnsureSendSocketCreated();

            lock (_SendSocketSynchroniser)
            {
                var sockets = _sendSockets.Where(i => i.LocalIPAddress.AddressFamily == fromLocalIpAddress.AddressFamily);

                // Send from the Any socket and the socket with the matching address
                if (fromLocalIpAddress.AddressFamily == IpAddressFamily.InterNetwork)
                {
                    sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.Any) || fromLocalIpAddress.Equals(i.LocalIPAddress));

                    // If sending to the loopback address, filter the socket list as well
                    if (destination.IpAddress.Equals(IpAddressInfo.Loopback))
                    {
                        sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.Any) || i.LocalIPAddress.Equals(IpAddressInfo.Loopback));
                    }
                }
                else if (fromLocalIpAddress.AddressFamily == IpAddressFamily.InterNetworkV6)
                {
                    sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.IPv6Any) || fromLocalIpAddress.Equals(i.LocalIPAddress));

                    // If sending to the loopback address, filter the socket list as well
                    if (destination.IpAddress.Equals(IpAddressInfo.IPv6Loopback))
                    {
                        sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.IPv6Any) || i.LocalIPAddress.Equals(IpAddressInfo.IPv6Loopback));
                    }
                }

                return(sockets.ToList());
            }
        }
Beispiel #4
0
        /// <summary>
        /// Sends a message to a particular address (uni or multicast) and port.
        /// </summary>
        public async Task SendMessage(byte[] messageData, IpEndPointInfo destination, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken)
        {
            if (messageData == null)
            {
                throw new ArgumentNullException("messageData");
            }

            ThrowIfDisposed();

            var sockets = GetSendSockets(fromLocalIpAddress, destination);

            if (sockets.Count == 0)
            {
                return;
            }

            // SSDP spec recommends sending messages multiple times (not more than 3) to account for possible packet loss over UDP.
            for (var i = 0; i < SsdpConstants.UdpResendCount; i++)
            {
                var tasks = sockets.Select(s => SendFromSocket(s, messageData, destination, cancellationToken)).ToArray();
                await Task.WhenAll(tasks).ConfigureAwait(false);

                await Task.Delay(100, cancellationToken).ConfigureAwait(false);
            }
        }
Beispiel #5
0
        public Task SendToAsync(byte[] buffer, int offset, int size, IpEndPointInfo endPoint, CancellationToken cancellationToken)
        {
            var taskCompletion = new TaskCompletionSource <int>();

            Action <IAsyncResult> callback = callbackResult =>
            {
                try
                {
                    taskCompletion.TrySetResult(EndSendTo(callbackResult));
                }
                catch (Exception ex)
                {
                    taskCompletion.TrySetException(ex);
                }
            };

            var result = BeginSendTo(buffer, offset, size, endPoint, new AsyncCallback(callback), null);

            if (result.CompletedSynchronously)
            {
                callback(result);
            }

            cancellationToken.Register(() => taskCompletion.TrySetCanceled());

            return(taskCompletion.Task);
        }
Beispiel #6
0
        public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint, CancellationToken cancellationToken)
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            if (bytes == null)
            {
                throw new ArgumentNullException("bytes");
            }

            if (remoteEndPoint == null)
            {
                throw new ArgumentNullException("remoteEndPoint");
            }

            try
            {
                await _udpClient.SendToAsync(bytes, 0, bytes.Length, remoteEndPoint, cancellationToken).ConfigureAwait(false);

                _logger.Info("Udp message sent to {0}", remoteEndPoint);
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error sending message to {0}", ex, remoteEndPoint);
            }
        }
Beispiel #7
0
        public IAsyncResult BeginSendTo(byte[] buffer, int offset, int size, IpEndPointInfo endPoint, AsyncCallback callback, object state)
        {
            ThrowIfDisposed();

            var ipEndPoint = NetworkManager.ToIPEndPoint(endPoint);

            return(_Socket.BeginSendTo(buffer, offset, size, SocketFlags.None, ipEndPoint, callback, state));
        }
        public static IPEndPoint ToIPEndPoint(IpEndPointInfo endpoint)
        {
            if (endpoint == null)
            {
                return(null);
            }

            return(new IPEndPoint(ToIPAddress(endpoint.IpAddress), endpoint.Port));
        }
        private void OnResponseReceived(HttpResponseMessage data, IpEndPointInfo endPoint)
        {
            var handlers = this.ResponseReceived;

            if (handlers != null)
            {
                handlers(this, new ResponseReceivedEventArgs(data, endPoint));
            }
        }
Beispiel #10
0
        public UdpSocket(Socket socket, IpEndPointInfo endPoint)
        {
            if (socket == null)
            {
                throw new ArgumentNullException("socket");
            }

            _Socket = socket;
            _Socket.Connect(NetworkManager.ToIPEndPoint(endPoint));
        }
Beispiel #11
0
        public Task SendAsync(byte[] buffer, int size, IpEndPointInfo endPoint)
        {
            ThrowIfDisposed();

            if (buffer == null)
            {
                throw new ArgumentNullException("messageData");
            }
            if (endPoint == null)
            {
                throw new ArgumentNullException("endPoint");
            }

            var ipEndPoint = NetworkManager.ToIPEndPoint(endPoint);

#if NETSTANDARD1_6
            if (size != buffer.Length)
            {
                byte[] copy = new byte[size];
                Buffer.BlockCopy(buffer, 0, copy, 0, size);
                buffer = copy;
            }

            _Socket.SendTo(buffer, ipEndPoint);
            return(Task.FromResult(true));
#else
            var taskSource = new TaskCompletionSource <bool>();

            try
            {
                _Socket.BeginSendTo(buffer, 0, size, SocketFlags.None, ipEndPoint, result =>
                {
                    try
                    {
                        _Socket.EndSend(result);
                        taskSource.TrySetResult(true);
                    }
                    catch (Exception ex)
                    {
                        taskSource.TrySetException(ex);
                    }
                }, null);
            }
            catch (Exception ex)
            {
                taskSource.TrySetException(ex);
            }

            //_Socket.SendTo(messageData, new System.Net.IPEndPoint(IPAddress.Parse(RemoteEndPoint.IPAddress), RemoteEndPoint.Port));

            return(taskSource.Task);
#endif
        }
Beispiel #12
0
        public UdpSocket(Socket socket, IpEndPointInfo endPoint)
        {
            if (socket == null)
            {
                throw new ArgumentNullException(nameof(socket));
            }

            _Socket = socket;
            _Socket.Connect(NetworkManager.ToIPEndPoint(endPoint));

            InitReceiveSocketAsyncEventArgs();
        }
Beispiel #13
0
        private void SendDeviceSearchResponses(SsdpDevice device, IpEndPointInfo endPoint, IpAddressInfo receivedOnlocalIpAddress, CancellationToken cancellationToken)
        {
            bool isRootDevice = (device as SsdpRootDevice) != null;

            if (isRootDevice)
            {
                SendSearchResponse(SsdpConstants.UpnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), endPoint, receivedOnlocalIpAddress, cancellationToken);
            }

            SendSearchResponse(device.Udn, device, device.Udn, endPoint, receivedOnlocalIpAddress, cancellationToken);

            SendSearchResponse(device.FullDeviceType, device, GetUsn(device.Udn, device.FullDeviceType), endPoint, receivedOnlocalIpAddress, cancellationToken);
        }
Beispiel #14
0
        private static async Task <bool> CheckTunerAvailability(ISocket socket, IpAddressInfo remoteIp, int tuner, CancellationToken cancellationToken)
        {
            var ipEndPoint = new IpEndPointInfo(remoteIp, HdHomeRunPort);

            var lockkeyMsg = CreateGetMessage(tuner, "lockkey");
            await socket.SendToAsync(lockkeyMsg, 0, lockkeyMsg.Length, ipEndPoint, cancellationToken);

            var receiveBuffer = new byte[8192];
            var response      = await socket.ReceiveAsync(receiveBuffer, 0, receiveBuffer.Length, cancellationToken).ConfigureAwait(false);

            ParseReturnMessage(response.Buffer, response.ReceivedBytes, out string returnVal);

            return(string.Equals(returnVal, "none", StringComparison.OrdinalIgnoreCase));
        }
        private Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination, CancellationToken cancellationToken)
        {
            var sockets = _sendSockets;

            if (sockets != null)
            {
                sockets = sockets.ToList();

                var tasks = sockets.Select(s => SendFromSocket(s, messageData, destination, cancellationToken));
                return(Task.WhenAll(tasks));
            }

            return(Task.CompletedTask);
        }
        private async Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination, CancellationToken cancellationToken)
        {
            var sockets = _sendSockets;

            if (sockets != null)
            {
                sockets = sockets.ToList();

                foreach (var socket in sockets)
                {
                    await SendFromSocket(socket, messageData, destination, cancellationToken).ConfigureAwait(false);
                }
            }
        }
 private async Task SendFromSocket(IUdpSocket socket, byte[] messageData, IpEndPointInfo destination)
 {
     try
     {
         await socket.SendAsync(messageData, messageData.Length, destination).ConfigureAwait(false);
     }
     catch (ObjectDisposedException)
     {
     }
     catch (Exception ex)
     {
         _logger.ErrorException("Error sending socket message from {0} to {1}", ex, socket.LocalIPAddress.ToString(), destination.ToString());
     }
 }
        private Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken)
        {
            var sockets = _sendSockets;

            if (sockets != null)
            {
                sockets = sockets.ToList();

                var tasks = sockets.Where(s => (fromLocalIpAddress == null || fromLocalIpAddress.Equals(s.LocalIPAddress)))
                            .Select(s => SendFromSocket(s, messageData, destination, cancellationToken));
                return(Task.WhenAll(tasks));
            }

            return(Task.CompletedTask);
        }
Beispiel #19
0
        public async Task SendWithLockAsync(byte[] buffer, int size, IpEndPointInfo endPoint, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();

            //await _sendLock.WaitAsync(cancellationToken).ConfigureAwait(false);

            try
            {
                await SendAsync(buffer, size, endPoint, cancellationToken).ConfigureAwait(false);
            }
            finally
            {
                //_sendLock.Release();
            }
        }
        private async Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination)
        {
            var sockets = _sendSockets;

            if (sockets != null)
            {
                sockets = sockets.ToList();

                foreach (var socket in sockets)
                {
                    await socket.SendAsync(messageData, messageData.Length, destination).ConfigureAwait(false);
                }
            }

            ThrowIfDisposed();
        }
        private void SendDeviceSearchResponses(SsdpDevice device, IpEndPointInfo endPoint, IpAddressInfo receivedOnlocalIpAddress)
        {
            bool isRootDevice = (device as SsdpRootDevice) != null;

            if (isRootDevice)
            {
                SendSearchResponse(SsdpConstants.UpnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), endPoint, receivedOnlocalIpAddress);
                if (this.SupportPnpRootDevice)
                {
                    SendSearchResponse(SsdpConstants.PnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.PnpDeviceTypeRootDevice), endPoint, receivedOnlocalIpAddress);
                }
            }

            SendSearchResponse(device.Udn, device, device.Udn, endPoint, receivedOnlocalIpAddress);

            SendSearchResponse(device.FullDeviceType, device, GetUsn(device.Udn, device.FullDeviceType), endPoint, receivedOnlocalIpAddress);
        }
        private void OnRequestReceived(HttpRequestMessage data, IpEndPointInfo remoteEndPoint, IpAddressInfo receivedOnLocalIpAddress)
        {
            //SSDP specification says only * is currently used but other uri's might
            //be implemented in the future and should be ignored unless understood.
            //Section 4.2 - http://tools.ietf.org/html/draft-cai-ssdp-v1-03#page-11
            if (data.RequestUri.ToString() != "*")
            {
                return;
            }

            var handlers = this.RequestReceived;

            if (handlers != null)
            {
                handlers(this, new RequestReceivedEventArgs(data, remoteEndPoint, receivedOnLocalIpAddress));
            }
        }
 private async Task SendFromSocket(ISocket socket, byte[] messageData, IpEndPointInfo destination, CancellationToken cancellationToken)
 {
     try
     {
         await socket.SendToAsync(messageData, 0, messageData.Length, destination, cancellationToken).ConfigureAwait(false);
     }
     catch (ObjectDisposedException)
     {
     }
     catch (OperationCanceledException)
     {
     }
     catch (Exception ex)
     {
         _logger.LogError(ex, "Error sending socket message from {0} to {1}", socket.LocalIPAddress.ToString(), destination.ToString());
     }
 }
Beispiel #24
0
 public static void RemoveEndPoint(EndPointListener epl, IpEndPointInfo ep)
 {
     lock (ip_to_endpoints)
     {
         // Dictionary<int, EndPointListener> p
         Dictionary <int, EndPointListener> p;
         if (ip_to_endpoints.TryGetValue(ep.IpAddress.Address, out p))
         {
             p.Remove(ep.Port);
             if (p.Count == 0)
             {
                 ip_to_endpoints.Remove(ep.IpAddress.Address);
             }
         }
         epl.Close();
     }
 }
Beispiel #25
0
        private async Task ReleaseLockkey(ISocket tcpClient, uint lockKeyValue)
        {
            _logger.Info("HdHomerunManager.ReleaseLockkey {0}", lockKeyValue);

            var ipEndPoint = new IpEndPointInfo(_remoteIp, HdHomeRunPort);

            var releaseTarget = CreateSetMessage(_activeTuner, "target", "none", lockKeyValue);
            await tcpClient.SendToAsync(releaseTarget, 0, releaseTarget.Length, ipEndPoint, CancellationToken.None).ConfigureAwait(false);

            var receiveBuffer = new byte[8192];

            await tcpClient.ReceiveAsync(receiveBuffer, 0, receiveBuffer.Length, CancellationToken.None).ConfigureAwait(false);

            var releaseKeyMsg = CreateSetMessage(_activeTuner, "lockkey", "none", lockKeyValue);

            _lockkey = null;
            await tcpClient.SendToAsync(releaseKeyMsg, 0, releaseKeyMsg.Length, ipEndPoint, CancellationToken.None).ConfigureAwait(false);

            await tcpClient.ReceiveAsync(receiveBuffer, 0, receiveBuffer.Length, CancellationToken.None).ConfigureAwait(false);
        }
        private void ProcessMessage(string data, IpEndPointInfo endPoint, IpAddressInfo receivedOnLocalIpAddress)
        {
            //Responses start with the HTTP version, prefixed with HTTP/ while
            //requests start with a method which can vary and might be one we haven't
            //seen/don't know. We'll check if this message is a request or a response
            //by checking for the HTTP/ prefix on the start of the message.
            if (data.StartsWith("HTTP/", StringComparison.OrdinalIgnoreCase))
            {
                HttpResponseMessage responseMessage = null;
                try
                {
                    responseMessage = _ResponseParser.Parse(data);
                }
                catch (ArgumentException)
                {
                    // Ignore invalid packets.
                }

                if (responseMessage != null)
                {
                    OnResponseReceived(responseMessage, endPoint, receivedOnLocalIpAddress);
                }
            }
            else
            {
                HttpRequestMessage requestMessage = null;
                try
                {
                    requestMessage = _RequestParser.Parse(data);
                }
                catch (ArgumentException)
                {
                    // Ignore invalid packets.
                }

                if (requestMessage != null)
                {
                    OnRequestReceived(requestMessage, endPoint, receivedOnLocalIpAddress);
                }
            }
        }
Beispiel #27
0
        public EndPointListener(HttpListener listener, IpAddressInfo addr, int port, bool secure, ICertificate cert, ILogger logger, ICryptoProvider cryptoProvider, IStreamFactory streamFactory, ISocketFactory socketFactory, IMemoryStreamFactory memoryStreamFactory, ITextEncoding textEncoding)
        {
            this.listener        = listener;
            _logger              = logger;
            _cryptoProvider      = cryptoProvider;
            _streamFactory       = streamFactory;
            _socketFactory       = socketFactory;
            _memoryStreamFactory = memoryStreamFactory;
            _textEncoding        = textEncoding;

            this.secure = secure;
            this.cert   = cert;

            _enableDualMode = addr.Equals(IpAddressInfo.IPv6Any);
            endpoint        = new IpEndPointInfo(addr, port);

            prefixes     = new Dictionary <ListenerPrefix, HttpListener>();
            unregistered = new Dictionary <HttpConnection, HttpConnection>();

            CreateSocket();
        }
        private async void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, IpEndPointInfo endPoint, IpAddressInfo receivedOnlocalIpAddress)
        {
            var rootDevice = device.ToRootDevice();

            //var additionalheaders = FormatCustomHeadersForResponse(device);

            const string header = "HTTP/1.1 200 OK";

            var values = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            values["EXT"]           = "";
            values["DATE"]          = DateTime.UtcNow.ToString("r");
            values["CACHE-CONTROL"] = "max-age = 600";
            values["ST"]            = searchTarget;
            values["SERVER"]        = string.Format("{0}/{1} UPnP/1.0 RSSDP/{2}", _OSName, _OSVersion, ServerVersion);
            values["USN"]           = uniqueServiceName;
            values["LOCATION"]      = rootDevice.Location.ToString();

            var message = SsdpHelper.BuildMessage(header, values);

            try
            {
                await _CommsServer.SendMessage(System.Text.Encoding.UTF8.GetBytes(message), endPoint, receivedOnlocalIpAddress).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
            }

            //WriteTrace(String.Format("Sent search response to " + endPoint.ToString()), device);
        }
        private void ProcessSearchRequest(string mx, string searchTarget, IpEndPointInfo remoteEndPoint, IpAddressInfo receivedOnlocalIpAddress)
        {
            if (String.IsNullOrEmpty(searchTarget))
            {
                WriteTrace(String.Format("Invalid search request received From {0}, Target is null/empty.", remoteEndPoint.ToString()));
                return;
            }

            //WriteTrace(String.Format("Search Request Received From {0}, Target = {1}", remoteEndPoint.ToString(), searchTarget));

            if (IsDuplicateSearchRequest(searchTarget, remoteEndPoint))
            {
                //WriteTrace("Search Request is Duplicate, ignoring.");
                return;
            }

            //Wait on random interval up to MX, as per SSDP spec.
            //Also, as per UPnP 1.1/SSDP spec ignore missing/bank MX header. If over 120, assume random value between 0 and 120.
            //Using 16 as minimum as that's often the minimum system clock frequency anyway.
            int maxWaitInterval = 0;

            if (String.IsNullOrEmpty(mx))
            {
                //Windows Explorer is poorly behaved and doesn't supply an MX header value.
                //if (this.SupportPnpRootDevice)
                mx = "1";
                //else
                //return;
            }

            if (!Int32.TryParse(mx, out maxWaitInterval) || maxWaitInterval <= 0)
            {
                return;
            }

            if (maxWaitInterval > 120)
            {
                maxWaitInterval = _Random.Next(0, 120);
            }

            //Do not block synchronously as that may tie up a threadpool thread for several seconds.
            Task.Delay(_Random.Next(16, (maxWaitInterval * 1000))).ContinueWith((parentTask) =>
            {
                //Copying devices to local array here to avoid threading issues/enumerator exceptions.
                IEnumerable <SsdpDevice> devices = null;
                lock (_Devices)
                {
                    if (String.Compare(SsdpConstants.SsdpDiscoverAllSTHeader, searchTarget, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        devices = GetAllDevicesAsFlatEnumerable().ToArray();
                    }
                    else if (String.Compare(SsdpConstants.UpnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 || (this.SupportPnpRootDevice && String.Compare(SsdpConstants.PnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0))
                    {
                        devices = _Devices.ToArray();
                    }
                    else if (searchTarget.Trim().StartsWith("uuid:", StringComparison.OrdinalIgnoreCase))
                    {
                        devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.Uuid, searchTarget.Substring(5), StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray();
                    }
                    else if (searchTarget.StartsWith("urn:", StringComparison.OrdinalIgnoreCase))
                    {
                        devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.FullDeviceType, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray();
                    }
                }

                if (devices != null)
                {
                    var deviceList = devices.ToList();
                    //WriteTrace(String.Format("Sending {0} search responses", deviceList.Count));

                    foreach (var device in deviceList)
                    {
                        SendDeviceSearchResponses(device, remoteEndPoint, receivedOnlocalIpAddress);
                    }
                }
                else
                {
                    //WriteTrace(String.Format("Sending 0 search responses."));
                }
            });
        }
 /// <summary>
 /// Full constructor.
 /// </summary>
 public ResponseReceivedEventArgs(HttpResponseMessage message, IpEndPointInfo receivedFrom)
 {
     _Message      = message;
     _ReceivedFrom = receivedFrom;
 }