コード例 #1
0
        /// <inheritdoc />
        internal override void StartListening(EndPoint desiredLocalListenEndPoint, bool useRandomPortFailOver)
        {
            if (desiredLocalListenEndPoint.GetType() != typeof(IPEndPoint))
            {
                throw new ArgumentException("Invalid desiredLocalListenEndPoint type provided.", "desiredLocalListenEndPoint");
            }
            if (IsListening)
            {
                throw new InvalidOperationException("Attempted to call StartListening when already listening.");
            }

            IPEndPoint desiredLocalListenIPEndPoint = (IPEndPoint)desiredLocalListenEndPoint;

            try
            {
                UDPConnection = new UDPConnection(new ConnectionInfo(ConnectionType.UDP, new IPEndPoint(IPAddress.Any, 0), desiredLocalListenIPEndPoint, ApplicationLayerProtocol, this), ListenerDefaultSendReceiveOptions, UDPOptions, true);
            }
            catch (SocketException)
            {
                if (useRandomPortFailOver)
                {
                    try
                    {
                        UDPConnection = new UDPConnection(new ConnectionInfo(ConnectionType.UDP, new IPEndPoint(IPAddress.Any, 0), new IPEndPoint(desiredLocalListenIPEndPoint.Address, 0), ApplicationLayerProtocol, this), ListenerDefaultSendReceiveOptions, UDPOptions, true);
                    }
                    catch (SocketException)
                    {
                        //If we get another socket exception this appears to be a bad IP. We will just ignore this IP
                        if (NetworkComms.LoggingEnabled)
                        {
                            NetworkComms.Logger.Error("It was not possible to open a random port on " + desiredLocalListenIPEndPoint.Address + ". This endPoint may not support listening or possibly try again using a different port.");
                        }
                        throw new CommsSetupShutdownException("It was not possible to open a random port on " + desiredLocalListenIPEndPoint.Address + ". This endPoint may not support listening or possibly try again using a different port.");
                    }
                }
                else
                {
                    if (NetworkComms.LoggingEnabled)
                    {
                        NetworkComms.Logger.Error("It was not possible to open port #" + desiredLocalListenIPEndPoint.Port.ToString() + " on " + desiredLocalListenIPEndPoint.Address + ". This endPoint may not support listening or possibly try again using a different port.");
                    }
                    throw new CommsSetupShutdownException("It was not possible to open port #" + desiredLocalListenIPEndPoint.Port.ToString() + " on " + desiredLocalListenIPEndPoint.Address + ". This endPoint may not support listening or possibly try again using a different port.");
                }
            }

#if WINDOWS_PHONE || NETFX_CORE
            this.LocalListenEndPoint = new IPEndPoint(IPAddress.Parse(UDPConnection.socket.Information.LocalAddress.DisplayName.ToString()), int.Parse(UDPConnection.socket.Information.LocalPort));
#else
            this.LocalListenEndPoint = (IPEndPoint)UDPConnection.udpClient.LocalIPEndPoint;
#endif
            this.IsListening = true;
        }
コード例 #2
0
        /// <summary>
        /// Sends a <see cref="Packet"/> to the provided endPoint. Offers more performance if an identical packet is being sent to multiple peers.
        /// NOTE: Any possible reply will be ignored unless listening for incoming UDP packets.
        /// </summary>
        /// <typeparam name="packetPayloadObjectType">The type of object encapsulated by the provided packet</typeparam>
        /// <param name="packetToSend">The packet to send</param>
        /// <param name="ipEndPoint">The destination IPEndPoint. Supports multicast endpoints.</param>
        /// <param name="sendReceiveOptions">The sendReceiveOptions to use for this send</param>
        /// <param name="applicationLayerProtocol">If enabled NetworkComms.Net uses a custom
        /// application layer protocol to provide useful features such as inline serialisation,
        /// transparent packet transmission, remote peer handshake and information etc. We strongly
        /// recommend you use the NetworkComms.Net application layer protocol.</param>
        public static void SendObject <packetPayloadObjectType>(IPacket packetToSend, IPEndPoint ipEndPoint, SendReceiveOptions sendReceiveOptions, ApplicationLayerProtocolStatus applicationLayerProtocol)
        {
            if (ipEndPoint == null)
            {
                throw new ArgumentNullException("ipEndPoint");
            }
            if (sendReceiveOptions == null)
            {
                throw new ArgumentNullException("sendReceiveOptions");
            }

            if (applicationLayerProtocol == ApplicationLayerProtocolStatus.Undefined)
            {
                throw new ArgumentException("A value of ApplicationLayerProtocolStatus.Undefined is invalid when using this method.", "applicationLayerProtocol");
            }

            if (sendReceiveOptions.Options.ContainsKey("ReceiveConfirmationRequired"))
            {
                throw new ArgumentException("Attempted to use a rouge UDP sender when the provided send receive" +
                                            " options specified the ReceiveConfirmationRequired option, which is unsupported. Please create a specific connection" +
                                            "instance to use this feature.", "sendReceiveOptions");
            }

            //Check the send receive options
            if (applicationLayerProtocol == ApplicationLayerProtocolStatus.Disabled)
            {
                if (sendReceiveOptions.DataSerializer != DPSManager.GetDataSerializer <NullSerializer>())
                {
                    throw new ArgumentException("Attempted to use a rouge UDP sender when the provided send receive" +
                                                " options serialiser was not NullSerializer. Please provide compatible send receive options in order to successfully" +
                                                " instantiate this unmanaged connection.", "sendReceiveOptions");
                }

                if (sendReceiveOptions.DataProcessors.Count > 0)
                {
                    throw new ArgumentException("Attempted to use a rouge UDP sender when the provided send receive" +
                                                " options contains data processors. Data processors may not be used with unmanaged connections." +
                                                " Please provide compatible send receive options in order to successfully instantiate this unmanaged connection.", "sendReceiveOptions");
                }
            }

            List <UDPConnection> connectionsToUse = null;

            //If we are already listening on what will be the outgoing adaptor we can send with that client to ensure reply packets are collected
            //The exception here is the broadcasting which goes out all adaptors
            if (ipEndPoint.Address != IPAddress.Broadcast)
            {
                #region Discover best local endpoint

                //Initialise best local end point as match all
                IPEndPoint bestLocalEndPoint = new IPEndPoint(IPAddress.Any, 0);
                try
                {
                    bestLocalEndPoint = IPTools.BestLocalEndPoint(ipEndPoint);
                    //Set the port to 0 to match all.
                    bestLocalEndPoint.Port = 0;
                }
                catch (SocketException ex)
                {
                    throw new ConnectionSetupException("Attempting to determine the best local endPoint to connect to " + ipEndPoint + " resulted in a socket exception.", ex);
                }
                catch (Exception ex)
                {
                    LogTools.LogException(ex, "BestLocalEndPointError", "Error while attempting to determine the best local end point to contact " + ipEndPoint.ToString());
                }

                #endregion Discover best local endpoint

                #region Check For Existing Local Listener

                List <UDPConnectionListener> existingListeners = Connection.ExistingLocalListeners <UDPConnectionListener>(bestLocalEndPoint);

                for (int i = 0; i < existingListeners.Count; i++)
                {
                    if (existingListeners[i].UDPConnection.ConnectionInfo.ApplicationLayerProtocol == applicationLayerProtocol)
                    {
                        connectionsToUse = new List <UDPConnection> {
                            existingListeners[i].UDPConnection
                        };

                        //Once we have a matching connection we can break
                        break;
                    }
                }

                #endregion Check For Existing Local Listener

                //If we have not picked up an existing listener we need to use/create a rougeSender
                if (connectionsToUse == null)
                {
                    #region Check For Suitable Rouge Sender

                    lock (udpRogueSenderCreationLocker)
                    {
                        if (NetworkComms.commsShutdown)
                        {
                            throw new CommunicationException("Attempting to send UDP packet but NetworkCommsDotNet is in the process of shutting down.");
                        }
                        else
                        {
                            if (!udpRogueSenders.ContainsKey(applicationLayerProtocol) ||
                                !udpRogueSenders[applicationLayerProtocol].ContainsKey(bestLocalEndPoint) ||
                                udpRogueSenders[applicationLayerProtocol][bestLocalEndPoint].ConnectionInfo.ConnectionState == ConnectionState.Shutdown)
                            {
                                //Create a new rogue sender
                                if (NetworkComms.LoggingEnabled)
                                {
                                    NetworkComms.Logger.Trace("Creating UDPRougeSender.");
                                }

                                if (!udpRogueSenders.ContainsKey(applicationLayerProtocol))
                                {
                                    udpRogueSenders.Add(applicationLayerProtocol, new Dictionary <IPEndPoint, UDPConnection>());
                                }

                                IPAddress anyRemoteIP = AnyRemoteIPAddress(ipEndPoint.AddressFamily);
                                udpRogueSenders[applicationLayerProtocol][bestLocalEndPoint] = new UDPConnection(new ConnectionInfo(ConnectionType.UDP, new IPEndPoint(anyRemoteIP, 0), bestLocalEndPoint, applicationLayerProtocol), sendReceiveOptions, UDPConnection.DefaultUDPOptions, false);
                            }

                            connectionsToUse = new List <UDPConnection> {
                                udpRogueSenders[applicationLayerProtocol][bestLocalEndPoint]
                            };
                        }
                    }

                    #endregion Check For Suitable Rouge Sender
                }
            }
            else
            {
                #region Get A Sender On All Interfaces For Broadcast

                lock (udpRogueSenderCreationLocker)
                {
                    //We do something special for broadcasts by selected EVERY adaptor
                    if (NetworkComms.LoggingEnabled)
                    {
                        NetworkComms.Logger.Trace("Getting senders for UDP broadcasting.");
                    }

                    if (!udpRogueSenders.ContainsKey(applicationLayerProtocol))
                    {
                        udpRogueSenders.Add(applicationLayerProtocol, new Dictionary <IPEndPoint, UDPConnection>());
                    }

                    connectionsToUse = new List <UDPConnection>();

                    //This is a broadcast and we need to send the broadcast over every local adaptor
                    List <IPAddress> validLocalIPAddresses = HostInfo.IP.FilteredLocalAddresses();
                    foreach (IPAddress address in validLocalIPAddresses)
                    {
                        IPEndPoint currentLocalIPEndPoint = new IPEndPoint(address, 0);
                        List <UDPConnectionListener> existingListeners = Connection.ExistingLocalListeners <UDPConnectionListener>(currentLocalIPEndPoint);

                        //If there is an existing listener we use that
                        if (existingListeners.Count > 0)
                        {
                            for (int i = 0; i < existingListeners.Count; i++)
                            {
                                if (existingListeners[i].UDPConnection.ConnectionInfo.ApplicationLayerProtocol == applicationLayerProtocol)
                                {
                                    connectionsToUse.Add(existingListeners[i].UDPConnection);

                                    //Once we have a matching connection we can break
                                    break;
                                }
                            }
                        }
                        else
                        {
                            //If not we check the rouge senders
                            if (!udpRogueSenders[applicationLayerProtocol].ContainsKey(currentLocalIPEndPoint) ||
                                udpRogueSenders[applicationLayerProtocol][currentLocalIPEndPoint].ConnectionInfo.ConnectionState == ConnectionState.Shutdown)
                            {
                                IPAddress anyRemoteIP = AnyRemoteIPAddress(currentLocalIPEndPoint.AddressFamily);

                                udpRogueSenders[applicationLayerProtocol][currentLocalIPEndPoint] = new UDPConnection(new ConnectionInfo(ConnectionType.UDP, new IPEndPoint(anyRemoteIP, 0), currentLocalIPEndPoint, applicationLayerProtocol), sendReceiveOptions, UDPConnection.DefaultUDPOptions, false);
                            }

                            connectionsToUse.Add(udpRogueSenders[applicationLayerProtocol][currentLocalIPEndPoint]);
                        }
                    }
                }

                #endregion Get A Sender On All Interfaces For Broadcast
            }

            foreach (UDPConnection connection in connectionsToUse)
            {
                try
                {
                    //This has been commented out for the time being as it made no difference to the broadcast issue
                    //we were investigating at the time we had issues
                    //Use the network broadcast address instead of the global broadcast address where possible
                    //if (ipEndPoint.Address == IPAddress.Broadcast && connection.ConnectionInfo.LocalIPEndPoint.AddressFamily == AddressFamily.InterNetwork)
                    //{
                    //    IPEndPoint ipEndPointToUse = new IPEndPoint(IPTools.GetIPv4NetworkBroadcastAddress(connection.ConnectionInfo.LocalIPEndPoint.Address), ipEndPoint.Port);
                    //    connection.SendPacketSpecific<packetPayloadObjectType>(packetToSend, ipEndPointToUse);
                    //}
                    //else
                    connection.SendPacketSpecific <packetPayloadObjectType>(packetToSend, ipEndPoint);
                }
                catch (SocketException) { /* Ignore any socket exceptions */ }
            }

            //Dispose of the packet
            packetToSend.Dispose();
        }
コード例 #3
0
        /// <summary>
        /// Internal UDP creation method that performs the necessary tasks
        /// </summary>
        /// <param name="connectionInfo"></param>
        /// <param name="defaultSendReceiveOptions"></param>
        /// <param name="level"></param>
        /// <param name="listenForReturnPackets"></param>
        /// <param name="existingListenerConnection"></param>
        /// <param name="possibleHandshakeUDPDatagram"></param>
        /// <param name="establishIfRequired">Will establish the connection, triggering connection establish delegates if a new
        /// connection is returned</param>
        /// <returns></returns>
        internal static UDPConnection GetConnection(ConnectionInfo connectionInfo, UDPOptions level, SendReceiveOptions defaultSendReceiveOptions, bool listenForReturnPackets, UDPConnection existingListenerConnection, HandshakeUDPDatagram possibleHandshakeUDPDatagram, bool establishIfRequired = true)
        {
            connectionInfo.ConnectionType = ConnectionType.UDP;

            bool          newConnection = false;
            UDPConnection connection    = null;

            lock (NetworkComms.globalDictAndDelegateLocker)
            {
                List <Connection> existingConnections = NetworkComms.GetExistingConnection(connectionInfo.RemoteIPEndPoint, connectionInfo.LocalIPEndPoint, ConnectionType.UDP, connectionInfo.ApplicationLayerProtocol);
                if (existingConnections.Count > 0)
                {
                    connection = (UDPConnection)existingConnections[0];
                }
                else
                {
                    //If we are listening on what will be the outgoing adaptor we send with that client to ensure if our connection info is handed off we are connectable by others
                    if (existingListenerConnection == null)
                    {
                        try
                        {
                            IPEndPoint localEndPoint = IPTools.BestLocalEndPoint(connectionInfo.RemoteIPEndPoint);
                            //Set the port to 0 so that we match any listener
                            localEndPoint.Port = 0;
                            List <UDPConnectionListener> existingListeners = Connection.ExistingLocalListeners <UDPConnectionListener>(localEndPoint);

                            for (int i = 0; i < existingListeners.Count; i++)
                            {
                                if (existingListeners[i].UDPConnection.ConnectionInfo.ApplicationLayerProtocol == connectionInfo.ApplicationLayerProtocol)
                                {
                                    existingListenerConnection = existingListeners[i].UDPConnection;

                                    //If we are using an existing listener there is no need to listen for packets
                                    listenForReturnPackets = false;

                                    //Once we have a matching connection we can break
                                    break;
                                }
                            }
                        }
                        catch (Exception)
                        {
                            if (NetworkComms.LoggingEnabled)
                            {
                                NetworkComms.Logger.Trace("Failed to determine preferred existing udpClientListener to " + connectionInfo.RemoteIPEndPoint.Address + ":" + connectionInfo.RemoteIPEndPoint.Port.ToString() + ". Will create an isolated UDP connection instead.");
                            }
                        }
                    }

                    //If an existing connection does not exist but the info we are using suggests it should we need to reset the info
                    //so that it can be reused correctly. This case generally happens when using Comms in the format
                    //UDPConnection.GetConnection(info).SendObject(packetType, objToSend);
                    if (connectionInfo.ConnectionState == ConnectionState.Established || connectionInfo.ConnectionState == ConnectionState.Shutdown)
                    {
                        connectionInfo.ResetConnectionInfo();
                    }

                    connection    = new UDPConnection(connectionInfo, defaultSendReceiveOptions, level, listenForReturnPackets, existingListenerConnection);
                    newConnection = true;
                }
            }

            //If we expect a UDP handshake we need to handle incoming datagrams here, if we have it available,
            //  before trying to establish the connection.
            //This is different for TCP connections because things happen in the reverse order
            //UDP - Already listening, receive connectionsetup, configure connection
            //TCP - Receive TCPClient, configure connection, start listening for connectionsetup, wait for connectionsetup
            //
            //possibleHandshakeUDPDatagram will only be set when GetConnection() is called from a listener
            //If multiple threads try to create an outgoing UDP connection to the same endPoint all but the originating
            //thread will be held on connection.WaitForConnectionEstablish();
            if (possibleHandshakeUDPDatagram != null &&
                (connection.ConnectionUDPOptions & UDPOptions.Handshake) == UDPOptions.Handshake)
            {
                lock (connection.packetBuilder.Locker)
                {
                    if (NetworkComms.LoggingEnabled)
                    {
                        NetworkComms.Logger.Trace(" ... " + possibleHandshakeUDPDatagram.DatagramBytes.Length.ToString() + " handshake bytes added to packetBuilder for " + connection.ConnectionInfo + ". Cached " + connection.packetBuilder.TotalBytesCached.ToString() + " bytes, expecting " + connection.packetBuilder.TotalBytesExpected.ToString() + " bytes.");
                    }

                    connection.packetBuilder.AddPartialPacket(possibleHandshakeUDPDatagram.DatagramBytes.Length, possibleHandshakeUDPDatagram.DatagramBytes);
                    if (connection.packetBuilder.TotalBytesCached > 0)
                    {
                        connection.IncomingPacketHandleHandOff(connection.packetBuilder);
                    }
                }

                if (connection.packetBuilder.TotalPartialPacketCount > 0)
                {
                    LogTools.LogException(new Exception("Packet builder had " + connection.packetBuilder.TotalBytesCached + " bytes remaining after a call to IncomingPacketHandleHandOff with connection " + connection.ConnectionInfo + ". Until sequenced packets are implemented this indicates a possible error."), "UDPConnectionError");
                }

                possibleHandshakeUDPDatagram.DatagramHandled = true;
            }

            //We must perform the establish outside the lock as for TCP connections
            if (newConnection && establishIfRequired)
            {
                //Call establish on the connection if it is not a rogue sender or listener
                if (!connectionInfo.RemoteIPEndPoint.Address.Equals(IPAddress.Any) && !connectionInfo.RemoteIPEndPoint.Address.Equals(IPAddress.IPv6Any))
                {
                    connection.EstablishConnection();
                }
            }
            else if (!newConnection)
            {
                connection.WaitForConnectionEstablish(NetworkComms.ConnectionEstablishTimeoutMS);
            }

            //UDP does not need keep alives
            //if (!NetworkComms.commsShutdown)
            //    TriggerConnectionKeepAliveThread();

            return(connection);
        }
コード例 #4
0
        /// <summary>
        /// Internal constructor for UDP connections
        /// </summary>
        /// <param name="connectionInfo"></param>
        /// <param name="defaultSendReceiveOptions"></param>
        /// <param name="level"></param>
        /// <param name="listenForIncomingPackets"></param>
        /// <param name="existingConnection"></param>
        internal UDPConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, UDPOptions level, bool listenForIncomingPackets, UDPConnection existingConnection = null)
            : base(connectionInfo, defaultSendReceiveOptions)
        {
            if (connectionInfo.ConnectionType != ConnectionType.UDP)
            {
                throw new ArgumentException("Provided connectionType must be UDP.", "connectionInfo");
            }

            if (NetworkComms.LoggingEnabled)
            {
                NetworkComms.Logger.Trace("Creating new UDPConnection with " + connectionInfo);
            }

            if (connectionInfo.ApplicationLayerProtocol == ApplicationLayerProtocolStatus.Disabled && level != UDPOptions.None)
            {
                throw new ArgumentException("If the application layer protocol has been disabled the provided UDPOptions can only be UDPOptions.None.");
            }

            ConnectionUDPOptions = level;

            if (listenForIncomingPackets && existingConnection != null)
            {
                throw new Exception("Unable to listen for incoming packets if an existing client has been provided. This is to prevent possible multiple accidently listens on the same client.");
            }

            if (existingConnection == null)
            {
                if (connectionInfo.RemoteIPEndPoint.Address.Equals(IPAddress.Any) || connectionInfo.RemoteIPEndPoint.Address.Equals(IPAddress.IPv6Any))
                {
#if WINDOWS_PHONE || NETFX_CORE
                    //We are creating an unbound endPoint, this is currently the rogue UDP sender and listeners only
                    socket = new DatagramSocket();

                    if (listenForIncomingPackets)
                    {
                        socket.MessageReceived += socket_MessageReceived;
                    }

                    socket.BindEndpointAsync(new HostName(ConnectionInfo.LocalIPEndPoint.Address.ToString()), ConnectionInfo.LocalIPEndPoint.Port.ToString()).AsTask().Wait();
#else
                    //We are creating an unbound endPoint, this is currently the rogue UDP sender and listeners only
                    udpClient = new UdpClientWrapper(new UdpClient(ConnectionInfo.LocalIPEndPoint));
#endif
                }
                else
                {
                    //If this is a specific connection we link to a default end point here
                    isIsolatedUDPConnection = true;

#if WINDOWS_PHONE || NETFX_CORE
                    if (ConnectionInfo.LocalEndPoint == null ||
                        (ConnectionInfo.LocalIPEndPoint.Address == IPAddress.Any && connectionInfo.LocalIPEndPoint.Port == 0) ||
                        (ConnectionInfo.LocalIPEndPoint.Address == IPAddress.IPv6Any && connectionInfo.LocalIPEndPoint.Port == 0))
                    {
                        socket = new DatagramSocket();

                        if (listenForIncomingPackets)
                        {
                            socket.MessageReceived += socket_MessageReceived;
                        }

                        socket.ConnectAsync(new HostName(ConnectionInfo.RemoteIPEndPoint.Address.ToString()), ConnectionInfo.RemoteIPEndPoint.Port.ToString()).AsTask().Wait();
                    }
                    else
                    {
                        socket = new DatagramSocket();

                        if (listenForIncomingPackets)
                        {
                            socket.MessageReceived += socket_MessageReceived;
                        }

                        EndpointPair pair = new EndpointPair(new HostName(ConnectionInfo.LocalIPEndPoint.Address.ToString()), ConnectionInfo.LocalIPEndPoint.Port.ToString(),
                                                             new HostName(ConnectionInfo.RemoteIPEndPoint.Address.ToString()), ConnectionInfo.RemoteIPEndPoint.Port.ToString());

                        socket.ConnectAsync(pair).AsTask().Wait();
                    }
#else
                    if (ConnectionInfo.LocalEndPoint == null)
                    {
                        udpClient = new UdpClientWrapper(new UdpClient(ConnectionInfo.RemoteEndPoint.AddressFamily));
                    }
                    else
                    {
                        udpClient = new UdpClientWrapper(new UdpClient(ConnectionInfo.LocalIPEndPoint));
                    }

                    //By calling connect we discard packets from anything other then the provided remoteEndPoint on our localEndPoint
                    udpClient.Connect(ConnectionInfo.RemoteIPEndPoint);
#endif
                }

#if !WINDOWS_PHONE && !NETFX_CORE
                //NAT traversal does not work in .net 2.0
                //Mono does not seem to have implemented AllowNatTraversal method and attempting the below method call will throw an exception
                //if (Type.GetType("Mono.Runtime") == null)
                //Allow NAT traversal by default for all udp clients
                //    udpClientThreadSafe.AllowNatTraversal(true);

                if (listenForIncomingPackets)
                {
                    StartIncomingDataListen();
                }
#endif
            }
            else
            {
                if (!existingConnection.ConnectionInfo.RemoteIPEndPoint.Address.Equals(IPAddress.Any))
                {
                    throw new Exception("If an existing udpClient is provided it must be unbound to a specific remoteEndPoint");
                }

#if WINDOWS_PHONE || NETFX_CORE
                //Using an exiting client allows us to send from the same port as for the provided existing connection
                this.socket = existingConnection.socket;
#else
                //Using an exiting client allows us to send from the same port as for the provided existing connection
                this.udpClient = existingConnection.udpClient;
#endif
            }

            IPEndPoint localEndPoint;
#if WINDOWS_PHONE || NETFX_CORE
            localEndPoint = new IPEndPoint(IPAddress.Parse(socket.Information.LocalAddress.DisplayName.ToString()), int.Parse(socket.Information.LocalPort));
#else
            localEndPoint = udpClient.LocalIPEndPoint;
#endif

            //We can update the localEndPoint so that it is correct
            if (!ConnectionInfo.LocalEndPoint.Equals(localEndPoint))
            {
                //We should now be able to set the connectionInfo localEndPoint
                NetworkComms.UpdateConnectionReferenceByEndPoint(this, ConnectionInfo.RemoteIPEndPoint, localEndPoint);
                ConnectionInfo.UpdateLocalEndPointInfo(localEndPoint);
            }
        }