示例#1
0
        private static void ForwardMessage(iRTVOMessage incomingMessage)
        {
            var allRelayConnections = NetworkComms.GetExistingConnection();// (from current in NetworkComms.GetExistingConnection() where current != connection select current).ToArray();

            incomingMessage.Source = NetworkComms.NetworkIdentifier;

            logger.Info("Forwarding Command {0} to {1} Clients", incomingMessage.Command, allRelayConnections.Count);
            //We will now send the message to every other connection
            foreach (var relayConnection in allRelayConnections)
            {
                if (relayConnection.ConnectionInfo.NetworkIdentifier == incomingMessage.Source)
                {
                    logger.Debug("Not sending redundant message to {0}", incomingMessage.Source);
                    continue;
                }
                //We ensure we perform the send within a try catch
                //To ensure a single failed send will not prevent the
                //relay to all working connections.
                try { relayConnection.SendObject("iRTVOMessage", incomingMessage); }
                catch (CommsException ex)
                {
                    logger.Warn("Broadcast to {0} failed: {1}", relayConnection, ex.ToString());
                }
            }
        }
示例#2
0
        // 某客户端用户的状态改变后,通知其他用户
        private void UserStateNotify(string userID, OnlineState ustate)
        {
            try
            {
                //用户状态契约类
                UserStateContract userState = new UserStateContract();
                userState.UserID = userID;
                userState.OnLine = ustate;
                IList <ShortGuid> allUserID;

                lock (syncLocker)
                {
                    //获取所有用户字典中的用户链接标识
                    allUserID = new List <ShortGuid>(userManager.Values);
                }

                //给所有用户发送某用户的在线状态
                foreach (ShortGuid netID in allUserID)
                {
                    List <Connection> result = NetworkComms.GetExistingConnection(netID, ConnectionType.TCP);

                    if (result.Count > 0 && result[0].ConnectionInfo.NetworkIdentifier == netID)
                    {
                        result[0].SendObject("UserStateNotify", userState);
                    }
                }
            }
            catch (Exception ex)
            {
                LogTools.LogException(ex, "MainForm.UserStateNotify");
            }
        }
 private void ProcessCommandAsHost(PacketHeader packetHeader, Connection connection, Command cmd)
 {
     foreach (Connection hostConnection in NetworkComms.GetExistingConnection(ConnectionType.TCP))
     {
         connection.SendObject("Command", cmd);
     }
 }
        public override void Run()
        {
            //Message to send
            Console.WriteLine("\nEnter a message to send all clients or \"quit\" and press ENTER:");

            string messageToSend;

            while ((messageToSend = Console.ReadLine()) != "quit")
            {
                if (!string.IsNullOrEmpty(messageToSend))
                {
                    foreach (Connection connection in NetworkComms.GetExistingConnection(ConnectionType.TCP))
                    {
                        connection.SendObject("Message", messageToSend);
                    }
                }
            }

            //The first available connection should become new host
            foreach (Connection connection in NetworkComms.GetExistingConnection(ConnectionType.TCP))
            {
                connection.SendObject("Config", NetworkComms.GetExistingConnection(ConnectionType.TCP).First().ConnectionInfo.RemoteEndPoint.ToString());
            }

            //We have used comms so we make sure to call shutdown
            NetworkComms.Shutdown();
        }
示例#5
0
 /// <summary>
 /// add incomming message on chat and relay it
 /// </summary>
 private void AppendToChat(Connection connection, Message incomingMessage)
 {
     if (lastPeerMessageDict.ContainsKey(incomingMessage.SourceIdentifier))
     {
         if (lastPeerMessageDict[incomingMessage.SourceIdentifier].MessageIndex < incomingMessage.MessageIndex)
         {
             AppendLineToRichChatBox("[" + (DateTime.Now).ToString(hourFormat) + "] " + incomingMessage.SourceName + " : " + incomingMessage.MessageContent);
             lastPeerMessageDict[incomingMessage.SourceIdentifier] = incomingMessage;
         }
     }
     else
     {
         lastPeerMessageDict.Add(incomingMessage.SourceIdentifier, incomingMessage);
         AppendLineToRichChatBox("[" + (DateTime.Now).ToString(hourFormat) + "] " + incomingMessage.SourceName + " : " + incomingMessage.MessageContent);
     }
     if (incomingMessage.RelayCount < relayMaximum)
     {
         var allRelayConnections = (from current in NetworkComms.GetExistingConnection() where current != connection select current).ToArray();
         incomingMessage.IncrementRelayCount();
         foreach (var relayConnection in allRelayConnections)
         {
             try
             { relayConnection.SendObject("Message", incomingMessage); }
             catch (CommsException)
             { /* Catch the comms exception, ignore and continue */ }
         }
     }
 }
示例#6
0
            /// <summary>
            /// Broadcast a message to all/specific client(s)
            /// </summary>
            /// <param name="messageForAll">message for all clients</param>
            /// <param name="messageForSender">message for specific client</param>
            private void BroadcastMessage(Connection connection, Message incomingMessage, string messageForAll, string messageForSender, string header = "CHAT")
            {
                var allRelayConnections = (from current in NetworkComms.GetExistingConnection() select current).ToArray();

                incomingMessage.IncrementRelayCount();
                foreach (var relayConnection in allRelayConnections)
                {
                    try
                    {
                        string msg;
                        if (connection == relayConnection)
                        {
                            msg = messageForSender;
                        }
                        else
                        {
                            msg = messageForAll;
                        }
                        if (!string.IsNullOrEmpty(msg))
                        {
                            Message message = new Message(NetworkComms.NetworkIdentifier, "Server", header, msg, messageSendIndex++);
                            lastPeerMessageDict[NetworkComms.NetworkIdentifier] = message;
                            relayConnection.SendObject("Message", message);
                        }
                    }
                    catch (CommsException)
                    {
                        // Catch the comms exception, ignore and continue
                    }
                }
            }
示例#7
0
        private void testTimer_Tick(object sender, EventArgs e)
        {
            List <Connection> currentConnections = NetworkComms.GetExistingConnection();

            lblConnCnt.Text = "Connected Clients: " + currentConnections.Count.ToString();

            txtInfo.Text = infoText;
        }
示例#8
0
        public void Send(Guid guid, PacketData packetData)
        {
            List <Connection> connections = NetworkComms.GetExistingConnection(guid, ConnectionType.TCP);

            foreach (Connection connection in connections)
            {
                TCPConnection.GetConnection(connection.ConnectionInfo).SendObject("Custom", packetData.ToPacket());
            }
        }
示例#9
0
        private void TurnOff()
        {
            List <Connection> currentConnections = NetworkComms.GetExistingConnection();

            foreach (Connection conn in currentConnections)
            {
                VRCommand cmd = new VRCommand(Enums.ControlMessage.TURN_OFF);
                SendCommandToClientSpecific(conn, cmd);
            }
        }
示例#10
0
        private void GetClientStatus()
        {
            List <Connection> currentConnections = NetworkComms.GetExistingConnection();

            foreach (Connection conn in currentConnections)
            {
                VRCommand cmd = new VRCommand(Enums.ControlMessage.STATUS);
                SendCommandToClientSpecific(conn, cmd);
            }
        }
示例#11
0
        private void buttonShowQuickHelp_Click(object sender, EventArgs e)
        {
            List <Connection> currentConnections = NetworkComms.GetExistingConnection();

            foreach (Connection conn in currentConnections)
            {
                VRCommand cmd = new VRCommand(Enums.ControlMessage.SHOW_QUICK_HELP);
                SendCommandToClientSpecific(conn, cmd);
            }
        }
示例#12
0
        public void CloseConnections()
        {
            List <Connection> oldConnections = NetworkComms.GetExistingConnection(ApplicationLayerProtocolStatus.Enabled);

            foreach (Connection c in oldConnections)
            {
                c.CloseConnection(false);
            }
            CommsNetworking.CloseConnection();
        }
示例#13
0
        /// <summary>
        /// Performs whatever functions we might so desire when we receive an incoming ChatMessage
        /// </summary>
        /// <param name="header">The PacketHeader corresponding with the received object</param>
        /// <param name="connection">The Connection from which this object was received</param>
        /// <param name="incomingMessage">The incoming ChatMessage we are after</param>
        private void HandleIncomingChatMessage(PacketHeader header, Connection connection, ChatMessage incomingMessage)
        {
            //We only want to write a message once to the chat window
            //Because we allow relaying and may receive the same message twice
            //we use our history and message indexes to ensure we have a new message
            lock (lastPeerMessageDict)
            {
                if (lastPeerMessageDict.ContainsKey(incomingMessage.SourceIdentifier))
                {
                    if (lastPeerMessageDict[incomingMessage.SourceIdentifier].MessageIndex < incomingMessage.MessageIndex)
                    {
                        //If this message index is greater than the last seen from this source we can safely
                        //write the message to the ChatBox
                        AppendLineToChatBox(incomingMessage.SourceName + " - " + incomingMessage.Message);

                        //We now replace the last received message with the current one
                        lastPeerMessageDict[incomingMessage.SourceIdentifier] = incomingMessage;
                    }
                }
                else
                {
                    //If we have never had a message from this source before then it has to be new
                    //by definition
                    lastPeerMessageDict.Add(incomingMessage.SourceIdentifier, incomingMessage);
                    AppendLineToChatBox(incomingMessage.SourceName + " - " + incomingMessage.Message);
                }
            }

            //Once we have written to the ChatBox we refresh the MessagesFromWindow
            RefreshMessagesFromBox();

            //This last section of the method is the relay function
            //We start by checking to see if this message has already been relayed
            //the maximum number of times
            if (incomingMessage.RelayCount < relayMaximum)
            {
                //If we are going to relay this message we need an array of
                //all other known connections
                var allRelayConnections = (from current in NetworkComms.GetExistingConnection() where current != connection select current).ToArray();

                //We increment the relay count before we send
                incomingMessage.IncrementRelayCount();

                //We will now send the message to every other connection
                foreach (var relayConnection in allRelayConnections)
                {
                    //We ensure we perform the send within a try catch
                    //To ensure a single failed send will not prevent the
                    //relay to all working connections.
                    try { relayConnection.SendObject("ChatMessage", incomingMessage); }
                    catch (CommsException) { /* Catch the comms exception, ignore and continue */ }
                }
            }
        }
示例#14
0
        private void buttonSendTileConfig_Click(object sender, EventArgs e)
        {
            List <Connection> currentConnections = NetworkComms.GetExistingConnection();
            TileConfig        tc = BuildMockTileData();

            foreach (Connection conn in currentConnections)
            {
                VRCommand cmd = new VRCommand(tc);

                SendCommandToClientSpecific(conn, cmd);
            }
        }
示例#15
0
        private void EndNow()
        {
            List <Connection> currentConnections = NetworkComms.GetExistingConnection();

            foreach (Connection conn in currentConnections)
            {
                EndNow endNow = new EndNow("Your time is up!" + Environment.NewLine +
                                           "Thanks for playing!");
                VRCommand cmd = new VRCommand(endNow);
                SendCommandToClientSpecific(conn, cmd);
            }
        }
示例#16
0
        // Print msg via ip for now.
        private void PrintIncMsg(PacketHeader packetHeader, Connection connection, string incomingObject)
        {
            String msg = connection.ToString() + ": " + incomingObject + "";

            ChatLog.Items.Add(msg);

            List <Connection> l = NetworkComms.GetExistingConnection();

            foreach (Connection i in l)
            {
                if (i != connection)
                {
                    i.SendObject(textBox1.Text);
                }
            }
        }
示例#17
0
            /// <summary>
            /// Deal with incomming message (print or subprocess)
            /// </summary>
            /// <param name="header">packet header</param>
            /// <param name="connection">connection</param>
            /// <param name="incomingMessage">message sent</param>
            private void HandleIncomingMessage(PacketHeader header, Connection connection, Message incomingMessage)
            {
                lock (lastPeerMessageDict)
                {
                    if (lastPeerMessageDict.ContainsKey(incomingMessage.SourceIdentifier))
                    {
                        if (lastPeerMessageDict[incomingMessage.SourceIdentifier].MessageIndex < incomingMessage.MessageIndex)
                        {
                            if (incomingMessage.coincheHeader == "CHAT")
                            {
                                AppendLineToRichChatBox("[" + (DateTime.Now).ToString("HH:mm:ss dd/MM/yyyy") + "] " + incomingMessage.SourceName + " : " + incomingMessage.MessageContent);
                                lastPeerMessageDict[incomingMessage.SourceIdentifier] = incomingMessage;
                            }
                        }
                        if (incomingMessage.coincheHeader != "CHAT")
                        {
                            HandleSpecificMessage(incomingMessage);
                        }
                    }
                    else
                    {
                        if (incomingMessage.coincheHeader == "CHAT")
                        {
                            lastPeerMessageDict.Add(incomingMessage.SourceIdentifier, incomingMessage);
                            AppendLineToRichChatBox("[" + (DateTime.Now).ToString("HH:mm:ss dd/MM/yyyy") + "] " + incomingMessage.SourceName + " : " + incomingMessage.MessageContent);
                        }
                        else
                        {
                            HandleSpecificMessage(incomingMessage);
                        }
                    }
                }

                if (incomingMessage.RelayCount < relayMaximum)
                {
                    var allRelayConnections = (from current in NetworkComms.GetExistingConnection() where current != connection select current).ToArray();

                    incomingMessage.IncrementRelayCount();

                    foreach (var relayConnection in allRelayConnections)
                    {
                        try { relayConnection.SendObject("Message", incomingMessage); }
                        catch (CommsException) { /* Catch the comms exception, ignore and continue */ }
                    }
                }
            }
示例#18
0
 private void button5_Click(object sender, EventArgs e)
 {
     try
     {
         lock (syncLocker)
         {
             LogInfo.LogMessage(DateTime.Now.ToString(), "查看连接信息");
             foreach (Connection conn in NetworkComms.GetExistingConnection())
             {
                 LogInfo.LogMessage("本地端点" + conn.ConnectionInfo.LocalEndPoint + "远程端点" + conn.ConnectionInfo.RemoteEndPoint, "查看连接信息");
             }
         }
     }
     catch (Exception ex)
     {
         LogTools.LogException(ex, "button5_Click");
     }
 }
示例#19
0
        /// <summary>
        /// Attempts to complete the connection establish with a minimum of locking to prevent possible deadlocking
        /// </summary>
        /// <param name="remoteConnectionInfo"><see cref="ConnectionInfo"/> corresponding with remoteEndPoint</param>
        /// <param name="possibleClashConnectionWithPeer_ByEndPoint">True if a connection already exists with provided remoteEndPoint</param>
        /// <param name="existingConnection">A reference to an existing connection if it exists</param>
        /// <returns>True if connection is successfully setup, otherwise false</returns>
        private bool ConnectionSetupHandlerFinal(ConnectionInfo remoteConnectionInfo, ref bool possibleClashConnectionWithPeer_ByEndPoint, ref Connection existingConnection)
        {
            lock (NetworkComms.globalDictAndDelegateLocker)
            {
                Connection connectionByEndPoint = NetworkComms.GetExistingConnection(ConnectionInfo.RemoteEndPoint, ConnectionInfo.ConnectionType);

                //If we no longer have the original endPoint reference (set in the constructor) then the connection must have been closed already
                if (connectionByEndPoint == null)
                {
                    connectionSetupException    = true;
                    connectionSetupExceptionStr = "Connection setup received after connection closure with " + ConnectionInfo;
                }
                else
                {
                    //We need to check for a possible GUID clash
                    //Probability of a clash is approx 0.1% if 1E19 connection are maintained simultaneously (This many connections has not be tested ;))
                    //but hey, we live in a crazy world!
                    if (remoteConnectionInfo.NetworkIdentifier == NetworkComms.NetworkIdentifier)
                    {
                        connectionSetupException    = true;
                        connectionSetupExceptionStr = "Remote peer has same network idendifier to local, " + remoteConnectionInfo.NetworkIdentifier + ". A real duplication is vanishingly improbable so this exception has probably been thrown because the local and remote application are the same.";
                    }
                    else if (connectionByEndPoint != this)
                    {
                        possibleClashConnectionWithPeer_ByEndPoint = true;
                        existingConnection = connectionByEndPoint;
                    }
                    else
                    {
                        //Update the connection info
                        //We never change the this.ConnectionInfo.RemoteEndPoint.Address as there might be NAT involved
                        //We may update the port however
                        IPEndPoint newRemoteIPEndPoint = new IPEndPoint(this.ConnectionInfo.RemoteEndPoint.Address, remoteConnectionInfo.LocalEndPoint.Port);
                        NetworkComms.UpdateConnectionReferenceByEndPoint(this, newRemoteIPEndPoint);

                        ConnectionInfo.UpdateInfoAfterRemoteHandshake(remoteConnectionInfo, newRemoteIPEndPoint);

                        return(true);
                    }
                }
            }

            return(false);
        }
示例#20
0
        //客户端获取在线的所有用户的p2p在线信息
        private void IncomingP2PInfo(PacketHeader header, Connection Connection, string param)
        {
            lock (syncLocker)
            {
                IList <UserIDEndPoint> userInfoList = new List <UserIDEndPoint>();
                //在用户字典中找到网络连接相对应的用户ID
                foreach (var kv in userManager)
                {
                    foreach (Connection conn in NetworkComms.GetExistingConnection(userManager[kv.Key], ConnectionType.TCP))
                    {
                        UserIDEndPoint userIDEndPoint = new UserIDEndPoint();
                        userIDEndPoint.UserID    = kv.Key;
                        userIDEndPoint.IPAddress = conn.ConnectionInfo.RemoteEndPoint.Address.ToString();
                        userIDEndPoint.Port      = conn.ConnectionInfo.RemoteEndPoint.Port;
                        userInfoList.Add(userIDEndPoint);
                    }
                }

                Connection.SendObject("ResP2pInfo", userInfoList);
            }
        }
示例#21
0
        public IPlayer Start()
        {
            Console.WriteLine("Game started....");
            var allRelayConnections = (from current in NetworkComms.GetExistingConnection() where current != null select current).ToArray();

            foreach (var relayConnection in allRelayConnections)
            {
                relayConnection.SendObject("Message", "Game started...");
            }
            List <string> playerNames = this.allPlayers.Select(x => x.Name).ToList();

            foreach (InternalPlayer player in this.allPlayers)
            {
                StartGameContext StartGameContext = new StartGameContext(playerNames, this.initialMoney);
                player.StartGame(StartGameContext);
                player.Connection.SendObject("StartGameContext", StartGameContext);
            }

            while (this.allPlayers.Count(x => x.PlayerMoney.Money > 0) > 1)
            {
                var smallBlind = SmallBlinds[(this.HandsPlayed) / 10];
                this.HandsPlayed++;
                IHandLogic hand = this.HandsPlayed % 2 == 1
                               ? new TwoPlayersHandLogic(new[] { this.firstPlayer, this.secondPlayer }, this.HandsPlayed, smallBlind)
                               : new TwoPlayersHandLogic(new[] { this.secondPlayer, this.firstPlayer }, this.HandsPlayed, smallBlind);

                hand.Play();
            }

            var winner = this.allPlayers.FirstOrDefault(x => x.PlayerMoney.Money > 0);

            foreach (var player in this.allPlayers)
            {
                EndGameContext EndGameContext = new EndGameContext(winner.Name);
                player.EndGame(EndGameContext);
                player.Connection.SendObject("EndGameContext", EndGameContext);
            }

            return(winner);
        }
示例#22
0
 private void button4_Click(object sender, EventArgs e)
 {
     try
     {
         lock (syncLocker)
         {
             LogInfo.LogMessage(DateTime.Now.ToString(), "查看连接数");
             foreach (Connection conn in NetworkComms.GetExistingConnection())
             {
                 //If true the remote end of the Connection responded to an alive/ping test
                 if (conn.ConnectionAlive())
                 {
                     LogInfo.LogMessage(conn.ConnectionInfo.RemoteEndPoint.ToString(), "查看连接数");
                 }
             }
         }
     }
     catch (Exception ex)
     {
         LogTools.LogException(ex, "button4_Click");
     }
 }
示例#23
0
        /// <summary>
        /// Writes the provided message to the console window
        /// </summary>
        /// <param name="header">The packet header associated with the incoming message</param>
        /// <param name="connection">The connection used by the incoming message</param>
        /// <param name="message">The message to be printed to the console</param>
        private static void ReceiveChatMessage(PacketHeader header, Connection connection, string message)
        {
            loggingTextBox.Invoke(new MethodInvoker(
                                      delegate()
            {
                loggingTextBox.AppendText(Environment.NewLine + "▶ A message was received" + connection.ToString() + " => " + message);

                // 스크롤 마지막으로 이동
                loggingTextBox.SelectionStart = loggingTextBox.Text.Length;
                loggingTextBox.ScrollToCaret();
            }));

            //UDPConnection.SendObject("Message", "Broadcast Message", new IPEndPoint(IPAddress.Broadcast, 1000));

            var allRelayConnections = (from current in NetworkComms.GetExistingConnection() where current != connection select current).ToArray();

            foreach (var relayConnection in allRelayConnections)
            {
                try { relayConnection.SendObject("SendChatMessage", message); }
                catch (CommsException) { /* Catch the general comms exception, ignore and continue */ }
            }

            //UDPConnection.SendObject("BroadMessage", "Broad Message", new IPEndPoint(IPAddress.Broadcast, 1000));
        }
示例#24
0
        public static void BroadcastMessage(iRTVOMessage m)
        {
            if (isServer)                                                       // Server Broadcasts to all clients
            {
                var allRelayConnections = NetworkComms.GetExistingConnection(); // (from current in NetworkComms.GetExistingConnection() where current != connection select current).ToArray();


                logger.Debug("Broadcasting Command {0} to {1} Clients", m.Command, allRelayConnections.Count);
                //We will now send the message to every other connection
                foreach (var relayConnection in allRelayConnections)
                {
                    //We ensure we perform the send within a try catch
                    //To ensure a single failed send will not prevent the
                    //relay to all working connections.
                    try { relayConnection.SendObject("iRTVOMessage", m); }
                    catch (CommsException ex)
                    {
                        logger.Warn("Broadcast to {0} failed: {1}", relayConnection, ex.ToString());
                    }
                }

                return;
            }
            else // Client only sends to server
            {
                if (serverConnection != null)
                {
                    logger.Debug("Sending Command '{0}' to Server", m.Command);
                    try { serverConnection.SendObject("iRTVOMessage", m); }
                    catch (CommsException ex)
                    {
                        logger.Error("Sending of Command '{0}' failed: {1}", m.Command, ex.ToString());
                    }
                }
            }
        }
示例#25
0
        public static void SendMessage(string targetClient, string Command, params object[] Arguments)
        {
            if (!isServer)
            {
                throw new UnauthorizedAccessException("Only the server can call this function!");
            }

            string[] args = new string[Arguments.Length];
            for (int i = 0; i < Arguments.Length; i++)
            {
                args[i] = Convert.ToString(Arguments[i]);
            }

            iRTVOMessage m = new iRTVOMessage(NetworkComms.NetworkIdentifier, Command, args);

            var allRelayConnections = NetworkComms.GetExistingConnection();// (from current in NetworkComms.GetExistingConnection() where current != connection select current).ToArray();


            logger.Info("Sending Command {0} to {1} ", Command, targetClient);
            //We will now send the message to every other connection
            foreach (var relayConnection in allRelayConnections)
            {
                if (relayConnection.ConnectionInfo.NetworkIdentifier != targetClient)
                {
                    continue;
                }
                //We ensure we perform the send within a try catch
                //To ensure a single failed send will not prevent the
                //relay to all working connections.
                try { relayConnection.SendObject("iRTVOMessage", m); }
                catch (CommsException ex)
                {
                    logger.Warn("Broadcast to {0} failed: {1}", relayConnection, ex.ToString());
                }
            }
        }
示例#26
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);
        }
示例#27
0
        /// <summary>
        /// The distributed file system (DFS) allows for the high performance distribution of large files
        /// within a cluster of peers. This sytem replicates the behaviour the bitTorrent protocol by using
        /// NetworkCommsDotNet. This example demonstrates the DFS in action.
        /// </summary>
        public static void RunExample()
        {
            //Select launch mode
            Console.WriteLine("Launching DFS system ...\n");
            Console.WriteLine("Please select host or peer mode:");
            Console.WriteLine("1 - Host Mode (Original source of data)");
            Console.WriteLine("2 - Peer Mode (Builds data and then acts as subhost)");

            //Read in user choice
            //if (Console.ReadKey(true).Key == ConsoleKey.D1) hostMode = true;
            //else hostMode = false;
            hostMode = false;

            if (hostMode)
            {
                //Prepare DFS in host mode
                #region ServerMode
                Console.WriteLine("\n ... host mode selected.");
                Console.WriteLine("\nPlease enter how large the test data packet should be in MB and press return, e.g. 50:");
                int numberMegsToCreate = int.Parse(Console.ReadLine());

                //Fill a byte[] with random data
                DateTime startTime      = DateTime.Now;
                Random   randGen        = new Random();
                byte[]   someRandomData = new byte[numberMegsToCreate * 1024 * 1024];
                randGen.NextBytes(someRandomData);

                Console.WriteLine("\n ... successfully created a {0}MB test packet.", ((double)someRandomData.Length / (1024.0 * 1024.0)).ToString("0.###"));

                object            listLocker       = new object();
                List <IPEndPoint> connectedClients = new List <IPEndPoint>();

                //Initialise the DFS before creating the test object to ensure the correct port and IP are used as the seed
                DFS.Initialise(10000);

                //Create the item to be distributed
                List <ConnectionInfo> seedConnectionInfoList = (from current in Connection.ExistingLocalListenEndPoints(ConnectionType.TCP) select new ConnectionInfo(ConnectionType.TCP, NetworkComms.NetworkIdentifier, current, true)).ToList();

                DistributedItem newItem = new DistributedItem("exampleItem", "example1", new MemoryStream(someRandomData), seedConnectionInfoList, DataBuildMode.Memory_Single);

                NetworkComms.ConnectionEstablishShutdownDelegate clientEstablishDelegate = (connection) =>
                {
                    lock (listLocker)
                        connectedClients.Remove((IPEndPoint)connection.ConnectionInfo.RemoteEndPoint);

                    Console.WriteLine("Client " + connection.ConnectionInfo + " connected.");
                };

                NetworkComms.ConnectionEstablishShutdownDelegate clientShutdownDelegate = (connection) =>
                {
                    lock (listLocker)
                        connectedClients.Remove((IPEndPoint)connection.ConnectionInfo.RemoteEndPoint);

                    Console.WriteLine("Client " + connection.ConnectionInfo + " disconnected.");
                };

                NetworkComms.PacketHandlerCallBackDelegate <int> ReplyDelegate = (packetHeader, connection, incomingObject) =>
                {
                    //Push the item into the swarm
                    lock (listLocker)
                        if (!connectedClients.Contains(connection.ConnectionInfo.RemoteEndPoint))
                        {
                            connectedClients.Add((IPEndPoint)connection.ConnectionInfo.RemoteEndPoint);
                        }

                    DFS.PushItemToPeer(connection, newItem, "BigDataRequestResponse");
                    Console.WriteLine("Pushing item to " + connection.ConnectionInfo + " (" + connection.ConnectionInfo.NetworkIdentifier + "). {0} in swarm. P#={1}, S#={2}.", connectedClients.Count, newItem.PushCount, newItem.TotalChunkSupplyCount);
                };

                NetworkComms.PacketHandlerCallBackDelegate <string> InfoDelegate = (packetHeader, connectionId, incomingString) =>
                {
                    Console.WriteLine(" ... " + connectionId + " - " + incomingString);
                };

                Console.WriteLine(" ... DFS has been initialised.");

                NetworkComms.AppendGlobalConnectionEstablishHandler(clientEstablishDelegate);
                NetworkComms.AppendGlobalConnectionCloseHandler(clientShutdownDelegate);
                NetworkComms.AppendGlobalIncomingPacketHandler("BigDataRequest", ReplyDelegate);
                NetworkComms.AppendGlobalIncomingPacketHandler("ClientInfo", InfoDelegate);

                Console.WriteLine("\nListening for incoming connections on:");
                foreach (IPEndPoint localEndPoint in Connection.ExistingLocalListenEndPoints(ConnectionType.TCP))
                {
                    Console.WriteLine("{0}:{1}", localEndPoint.Address, localEndPoint.Port);
                }

                Console.WriteLine("\nIdentifier - {0}", NetworkComms.NetworkIdentifier);
                Console.WriteLine("\nPress 's' to write out stats, 'q' to close any connected peers, 'ctrl+q' to close this host.\n");

                while (true)
                {
                    ConsoleKeyInfo pressedKey = Console.ReadKey(true);
                    #region Host Shutdown
                    if (pressedKey.Modifiers != ConsoleModifiers.Control && pressedKey.Key == ConsoleKey.Q)
                    {
                        Console.WriteLine("Sending shutdown to clients...");
                        lock (listLocker)
                        {
                            for (int i = 0; i < connectedClients.Count; i++)
                            {
                                try
                                {
                                    TCPConnection.GetConnection(new ConnectionInfo(connectedClients[i])).SendObject("ClientCommand", 0);
                                }
                                catch (Exception)
                                {
                                    Console.WriteLine("Exception telling client to shutdown. Probably already disconnected.");
                                }
                            }
                        }
                    }
                    else if (pressedKey.Modifiers == ConsoleModifiers.Control && pressedKey.Key == ConsoleKey.Q)
                    {
                        Console.WriteLine("Sending shutdown to clients and closing local host...");
                        lock (listLocker)
                        {
                            for (int i = 0; i < connectedClients.Count; i++)
                            {
                                try
                                {
                                    TCPConnection.GetConnection(new ConnectionInfo(connectedClients[i])).SendObject("ClientCommand", 0);
                                }
                                catch (Exception)
                                {
                                    Console.WriteLine("Exception telling client to shutdown. Probably already disconnected.");
                                }
                            }
                        }

                        Console.WriteLine("Closing host.");
                        break;
                    }
                    else if (pressedKey.Key == ConsoleKey.S)
                    {
                        #region Stats
                        Console.WriteLine("\nCurrent Stats:");
                        Console.WriteLine("{0} comms connections.", NetworkComms.TotalNumConnections());

                        if (NetworkComms.TotalNumConnections() > 0)
                        {
                            Console.WriteLine("Connections with: ");
                            var connections = NetworkComms.GetExistingConnection();
                            foreach (var connection in connections)
                            {
                                Console.WriteLine("\t{0}", connection.ConnectionInfo);
                            }
                        }
                        #endregion
                    }
                    #endregion
                }
                #endregion
            }
            else if (!hostMode)
            {
                //Prepare DFS in peer mode
                #region PeerMode
                Console.WriteLine("\n ... peer mode selected.");

                try
                {
                    ConnectionInfo serverConnectionInfo = new ConnectionInfo("192.168.0.105", 10000);
                    //ExampleHelper.GetServerDetails(out serverConnectionInfo);

                    DFS.Initialise(10000);
                    Console.WriteLine(" ... DFS has been initialised.");

                    bool     shutDown      = false;
                    bool     buildComplete = true;
                    DateTime startTime     = DateTime.Now;

                    int buildCount = 0;

                    NetworkComms.PacketHandlerCallBackDelegate <byte[]> ReplyDelegate = (packetHeader, connection, dataBytes) =>
                    {
                        try
                        {
                            buildCount++;
                            DistributedItem item = DFS.MostRecentlyCompletedItem();
                            Console.WriteLine(" ... full item build " + buildCount + " took {0} secs ({1} MB/s) using {2} total peers. {3} builds completed.", (DateTime.Now - startTime).TotalSeconds.ToString("0.00"), (((double)dataBytes.Length / 1048576.0) / (DateTime.Now - startTime).TotalSeconds).ToString("0.0"), item.SwarmChunkAvailability.NumPeersInSwarm(), buildCount);

                            double speed = (((double)dataBytes.Length / 1048576.0) / (DateTime.Now - startTime).TotalSeconds);
                            connection.SendObject("ClientInfo", " ... build " + buildCount + " took " + (DateTime.Now - startTime).TotalSeconds.ToString("0.00") + " secs (" + speed.ToString("0.0") + " MB/s) using " + item.SwarmChunkAvailability.NumPeersInSwarm() + " peers. " + buildCount + " builds completed.");
                            buildComplete = true;
                            dataBytes     = null;
                            GC.Collect();
                        }
                        catch (Exception ex)
                        {
                            LogTools.LogException(ex, "DFSTestCallbackError");
                            Console.WriteLine("Shutting down due to exception.");
                            shutDown = true;
                        }
                    };

                    NetworkComms.PacketHandlerCallBackDelegate <int> ShutdownDelegate = (packetHeader, connectionId, packetDataBytes) =>
                    {
                        shutDown = true;
                    };

                    NetworkComms.AppendGlobalIncomingPacketHandler("BigDataRequestResponse", ReplyDelegate);
                    NetworkComms.AppendGlobalIncomingPacketHandler("ClientCommand", ShutdownDelegate);

                    Console.WriteLine("\nIdentifier - {0}", NetworkComms.NetworkIdentifier);
                    Console.WriteLine("\nListening for incoming objects on:");
                    foreach (IPEndPoint localEndPoint in Connection.ExistingLocalListenEndPoints(ConnectionType.TCP))
                    {
                        Console.WriteLine("{0}:{1}", localEndPoint.Address, localEndPoint.Port);
                    }

                    startTime = DateTime.Now;

                    //while (true)
                    //{
                    if (!shutDown && buildComplete)
                    {
                        //Console.WriteLine("\nPress 'r' to rebuild or any other key to shutdown.");
                        //var shutdownKey = Console.ReadKey(true).Key;
                        //if (shutdownKey != ConsoleKey.R) shutDown = true;

                        //if (!shutDown)
                        //{
                        DistributedItem item = DFS.MostRecentlyCompletedItem();
                        if (item != null)
                        {
                            DFS.RemoveItem(item.Data.CompleteDataCheckSum);
                            Console.WriteLine("\n ... item removed from local and rebuilding at {0}.", DateTime.Now.ToString("HH:mm:ss.fff"));
                            startTime = DateTime.Now;
                        }

                        buildComplete = false;

                        TCPConnection.GetConnection(serverConnectionInfo).SendObject("BigDataRequest");

                        Console.WriteLine(" ... initiating item build ...");
                        //}
                    }
                    else if (shutDown)
                    {
                        shutDown = true;
                        DFS.Shutdown();
                        //break;
                    }

                    Thread.Sleep(250);
                    //}

                    while (!buildComplete)
                    {
                        Thread.Sleep(250);
                    }

                    try
                    {
                        TCPConnection.GetConnection(serverConnectionInfo).SendObject("ClientInfo", "... shutting down, initiating DFS shutdown.");
                    }
                    catch (CommsException)
                    {
                        Console.WriteLine("... unable to inform local of shutdown. Connection probably already closed.");
                    }

                    Console.WriteLine("Done. Completed {0} builds.", buildCount);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Bad Error!");
                    LogTools.LogException(ex, "DFSTestError_" + NetworkComms.NetworkIdentifier);
                }

                #endregion
            }

            DFS.Shutdown();
            NetworkComms.Shutdown();
        }
        /// <summary>
        /// Internal <see cref="TCPConnection"/> creation which hides the necessary internal calls
        /// </summary>
        /// <param name="connectionInfo">ConnectionInfo to be used to create connection</param>
        /// <param name="defaultSendReceiveOptions">Connection default SendReceiveOptions</param>
        /// <param name="tcpClient">If this is an incoming connection we will already have access to the tcpClient, otherwise use null</param>
        /// <param name="establishIfRequired">Establish during create if true</param>
        /// <param name="sslOptions">SSL options that will be used with this connection.</param>
        /// <returns>An existing connection or a new one</returns>
        internal static TCPConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, TcpClient tcpClient, bool establishIfRequired, SSLOptions sslOptions = null)
#endif
        {
            connectionInfo.ConnectionType = ConnectionType.TCP;

            //If we have a tcpClient at this stage we must be server side
#if WINDOWS_PHONE || NETFX_CORE
            if (socket != null)
            {
                connectionInfo.ServerSide = true;
            }
#else
            if (tcpClient != null)
            {
                connectionInfo.ServerSide = true;
            }
            if (sslOptions == null)
            {
                sslOptions = new SSLOptions();
            }
#endif

            //Set default connection options if none have been provided
            if (defaultSendReceiveOptions == null)
            {
                defaultSendReceiveOptions = NetworkComms.DefaultSendReceiveOptions;
            }

            bool          newConnection = false;
            TCPConnection connection;

            lock (NetworkComms.globalDictAndDelegateLocker)
            {
                List <Connection> existingConnections = NetworkComms.GetExistingConnection(connectionInfo.RemoteIPEndPoint, connectionInfo.LocalIPEndPoint, connectionInfo.ConnectionType, connectionInfo.ApplicationLayerProtocol);

                //Check to see if a connection already exists, if it does return that connection, if not return a new one
                if (existingConnections.Count > 0)
                {
                    if (NetworkComms.LoggingEnabled)
                    {
                        NetworkComms.Logger.Trace("Attempted to create new TCPConnection to connectionInfo='" + connectionInfo + "' but there is an existing connection. Existing connection will be returned instead.");
                    }

                    establishIfRequired = false;
                    connection          = (TCPConnection)existingConnections[0];
                }
                else
                {
                    if (NetworkComms.LoggingEnabled)
                    {
                        NetworkComms.Logger.Trace("Creating new TCPConnection to connectionInfo='" + connectionInfo + "'." + (establishIfRequired ? " Connection will be established." : " Connection will not be established."));
                    }

                    if (connectionInfo.ConnectionState == ConnectionState.Establishing)
                    {
                        throw new ConnectionSetupException("Connection state for connection " + connectionInfo + " is marked as establishing. This should only be the case here due to a bug.");
                    }

                    //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
                    //TCPConnection.GetConnection(info).SendObject(packetType, objToSend);
                    if (connectionInfo.ConnectionState == ConnectionState.Established || connectionInfo.ConnectionState == ConnectionState.Shutdown)
                    {
                        connectionInfo.ResetConnectionInfo();
                    }

                    //We add a reference to networkComms for this connection within the constructor
#if WINDOWS_PHONE || NETFX_CORE
                    connection = new TCPConnection(connectionInfo, defaultSendReceiveOptions, socket);
#else
                    connection = new TCPConnection(connectionInfo, defaultSendReceiveOptions, tcpClient, sslOptions);
#endif
                    newConnection = true;
                }
            }

            if (newConnection && establishIfRequired)
            {
                connection.EstablishConnection();
            }
            else if (!newConnection)
            {
                connection.WaitForConnectionEstablish(NetworkComms.ConnectionEstablishTimeoutMS);
            }

            if (!NetworkComms.commsShutdown)
            {
                TriggerConnectionKeepAliveThread();
            }

            return(connection);
        }
示例#29
0
        /// <summary>
        /// Attempts to complete the connection establish with a minimum of locking to avoid possible deadlocking
        /// </summary>
        /// <param name="remoteConnectionInfo"><see cref="ConnectionInfo"/> corresponding with remoteEndPoint</param>
        /// <param name="possibleClashWithExistingConnection">True if a connection already exists with provided remoteEndPoint</param>
        /// <param name="existingConnection">A reference to an existing connection if it exists</param>
        /// <returns>True if connection is successfully setup, otherwise false</returns>
        private bool ConnectionSetupHandlerFinal(ConnectionInfo remoteConnectionInfo, ref bool possibleClashWithExistingConnection, ref Connection existingConnection)
        {
            lock (NetworkComms.globalDictAndDelegateLocker)
            {
                List <Connection> connectionByEndPoint = NetworkComms.GetExistingConnection(ConnectionInfo.RemoteEndPoint, ConnectionInfo.LocalEndPoint, ConnectionInfo.ConnectionType, ConnectionInfo.ApplicationLayerProtocol);

                //If we no longer have the original endPoint reference (set in the constructor) then the connection must have been closed already
                if (connectionByEndPoint.Count == 0)
                {
                    connectionSetupException    = true;
                    connectionSetupExceptionStr = "Connection setup received after connection closure with " + ConnectionInfo;
                }
                else
                {
                    //COMMENT: As of version 3.0.0 we have allowed loop back connections where the identifier is the same
                    //We need to check for a possible GUID clash
                    //Probability of a clash is approx 0.1% if 1E19 connections are maintained simultaneously (This many connections has not be tested ;))
                    //but hey, we live in a crazy world!
                    //if (remoteConnectionInfo.NetworkIdentifier == NetworkComms.NetworkIdentifier)
                    //{
                    //    connectionSetupException = true;
                    //    connectionSetupExceptionStr = "Remote peer has same network identifier to local, " + remoteConnectionInfo.NetworkIdentifier + ". A real duplication is vanishingly improbable so this exception has probably been thrown because the local and remote application are the same.";
                    //}
                    //else
                    if (connectionByEndPoint[0] != this)
                    {
                        possibleClashWithExistingConnection = true;
                        existingConnection = connectionByEndPoint[0];
                    }
                    else if (connectionByEndPoint[0].ConnectionInfo.NetworkIdentifier != ShortGuid.Empty &&
                             connectionByEndPoint[0].ConnectionInfo.NetworkIdentifier != remoteConnectionInfo.NetworkIdentifier)
                    {
                        //We are in the same connection, so don't need to throw and exception but the remote network identifier
                        //has changed.
                        //This can happen for connection types where the local connection (this) may not have been closed
                        //when the remote peer closed. We need to trigger the connection close delegates with the old info, update
                        //the connection info and then call the establish delegates
                        #region Reset Connection without closing
                        //Call the connection close delegates
                        try
                        {
                            //Almost there
                            //Last thing is to call any connection specific shutdown delegates
                            if (ConnectionSpecificShutdownDelegate != null)
                            {
                                if (NetworkComms.LoggingEnabled)
                                {
                                    NetworkComms.Logger.Debug("Triggered connection specific shutdown delegates with " + ConnectionInfo);
                                }
                                ConnectionSpecificShutdownDelegate(this);
                            }
                        }
                        catch (Exception ex)
                        {
                            LogTools.LogException(ex, "ConnectionSpecificShutdownDelegateError", "Error while executing connection specific shutdown delegates for " + ConnectionInfo + ". Ensure any shutdown exceptions are caught in your own code.");
                        }

                        try
                        {
                            //Last but not least we call any global connection shutdown delegates
                            if (NetworkComms.globalConnectionShutdownDelegates != null)
                            {
                                if (NetworkComms.LoggingEnabled)
                                {
                                    NetworkComms.Logger.Debug("Triggered global shutdown delegates with " + ConnectionInfo);
                                }
                                NetworkComms.globalConnectionShutdownDelegates(this);
                            }
                        }
                        catch (Exception ex)
                        {
                            LogTools.LogException(ex, "GlobalConnectionShutdownDelegateError", "Error while executing global connection shutdown delegates for " + ConnectionInfo + ". Ensure any shutdown exceptions are caught in your own code.");
                        }

                        EndPoint newRemoteEndPoint;
                        if (this.ConnectionInfo.RemoteEndPoint.GetType() == typeof(IPEndPoint) &&
                            remoteConnectionInfo.LocalEndPoint.GetType() == typeof(IPEndPoint))
                        {
                            newRemoteEndPoint = new IPEndPoint(this.ConnectionInfo.RemoteIPEndPoint.Address, remoteConnectionInfo.LocalIPEndPoint.Port);
                        }
                        else
                        {
                            throw new NotImplementedException("ConnectionSetupHandlerFinal not implemented for EndPoints of type " + this.ConnectionInfo.RemoteEndPoint.GetType());
                        }

                        NetworkComms.UpdateConnectionReferenceByEndPoint(this, newRemoteEndPoint, this.ConnectionInfo.LocalEndPoint);

                        ConnectionInfo.UpdateInfoAfterRemoteHandshake(remoteConnectionInfo, newRemoteEndPoint);

                        //Trigger the establish delegates
                        TriggerConnectionEstablishDelegates();
                        #endregion

                        return(true);
                    }
                    else
                    {
                        //Update the connection info
                        //We never change the this.ConnectionInfo.RemoteEndPoint.Address as there might be NAT involved
                        //We may update the port however
                        EndPoint newRemoteEndPoint;
                        if (this is IPConnection)
                        {
                            newRemoteEndPoint = new IPEndPoint(this.ConnectionInfo.RemoteIPEndPoint.Address, remoteConnectionInfo.LocalIPEndPoint.Port);
                        }
#if NET35 || NET4
                        else if (this is BluetoothConnection)
                        {
                            newRemoteEndPoint = ConnectionInfo.RemoteBTEndPoint;
                        }
#endif
                        else
                        {
                            throw new NotImplementedException("ConnectionSetupHandlerFinal not implemented for EndPoints of type " + this.ConnectionInfo.RemoteEndPoint.GetType());
                        }

                        NetworkComms.UpdateConnectionReferenceByEndPoint(this, newRemoteEndPoint, this.ConnectionInfo.LocalEndPoint);

                        ConnectionInfo.UpdateInfoAfterRemoteHandshake(remoteConnectionInfo, newRemoteEndPoint);

                        return(true);
                    }
                }
            }

            return(false);
        }
示例#30
0
        /// <summary>
        /// Updates the configuration of this instance depending on set fields
        /// </summary>
        public void RefreshNetworkCommsConfiguration()
        {
            #region First Initialisation
            //On first initialisation we need to configure NetworkComms.Net to handle our incoming packet types
            //We only need to add the packet handlers once. If we call NetworkComms.Shutdown() at some future point these are not removed.
            if (FirstInitialisation)
            {
                FirstInitialisation = false;



                //Configure NetworkComms.Net to handle any incoming packet of type 'ChatMessage'
                //e.g. If we receive a packet of type 'ChatMessage' execute the method 'HandleIncomingChatMessage'
                NetworkComms.AppendGlobalIncomingPacketHandler <ChatMessage>("ChatMessage", HandleIncomingChatMessage);

                //Configure NetworkComms.Net to perform some action when a connection is closed
                //e.g. When a connection is closed execute the method 'HandleConnectionClosed'
                NetworkComms.AppendGlobalConnectionCloseHandler(HandleConnectionClosed);
            }
            #endregion

            #region Set serializer
            //Set the default send recieve options to use the specified serializer. Keep the DataProcessors and Options from the previous defaults
            NetworkComms.DefaultSendReceiveOptions = new SendReceiveOptions(Serializer, NetworkComms.DefaultSendReceiveOptions.DataProcessors, NetworkComms.DefaultSendReceiveOptions.Options);
            #endregion

            #region Optional Encryption
            //Configure encryption if requested
            if (EncryptionEnabled && !NetworkComms.DefaultSendReceiveOptions.DataProcessors.Contains(DPSManager.GetDataProcessor <RijndaelPSKEncrypter>()))
            {
                //Encryption is currently implemented using a pre-shared key (PSK) system
                //NetworkComms.Net supports multiple data processors which can be used with any level of granularity
                //To enable encryption globally (i.e. for all connections) we first add the encryption password as an option
                RijndaelPSKEncrypter.AddPasswordToOptions(NetworkComms.DefaultSendReceiveOptions.Options, _encryptionKey);
                //Finally we add the RijndaelPSKEncrypter data processor to the sendReceiveOptions
                NetworkComms.DefaultSendReceiveOptions.DataProcessors.Add(DPSManager.GetDataProcessor <RijndaelPSKEncrypter>());
            }
            else if (!EncryptionEnabled && NetworkComms.DefaultSendReceiveOptions.DataProcessors.Contains(DPSManager.GetDataProcessor <RijndaelPSKEncrypter>()))
            {
                //If encryption has been disabled but is currently enabled
                //To disable encryption we just remove the RijndaelPSKEncrypter data processor from the sendReceiveOptions
                NetworkComms.DefaultSendReceiveOptions.DataProcessors.Remove(DPSManager.GetDataProcessor <RijndaelPSKEncrypter>());
            }
            #endregion

            #region Local Server Mode and Connection Type Changes
            if (LocalServerEnabled && ConnectionType == ConnectionType.TCP && !Connection.Listening(ConnectionType.TCP))
            {
                //If we were previously listening for UDP we first shutdown NetworkComms.Net.
                if (Connection.Listening(ConnectionType.UDP))
                {
                    AppendLineToChatHistory("Connection mode has been changed. Any existing connections will be closed.");
                    NetworkComms.Shutdown();
                }
                else
                {
                    AppendLineToChatHistory("Enabling local server mode. Any existing connections will be closed.");
                    NetworkComms.Shutdown();
                }

                //Start listening for new incoming TCP connections
                //We want to select a random port on all available adaptors so provide
                //an IPEndPoint using IPAddress.Any and port 0.
                Connection.StartListening(ConnectionType.TCP, new IPEndPoint(IPAddress.Any, 0));

                //Write the IP addresses and ports that we are listening on to the chatBox
                AppendLineToChatHistory("Listening for incoming TCP connections on:");
                foreach (IPEndPoint listenEndPoint in Connection.ExistingLocalListenEndPoints(ConnectionType.TCP))
                {
                    AppendLineToChatHistory(listenEndPoint.Address + ":" + listenEndPoint.Port);
                }

                //Add a blank line after the initialisation output
                AppendLineToChatHistory(System.Environment.NewLine);
            }
            else if (LocalServerEnabled && ConnectionType == ConnectionType.UDP && !Connection.Listening(ConnectionType.UDP))
            {
                //If we were previously listening for TCP we first shutdown NetworkComms.Net.
                if (Connection.Listening(ConnectionType.TCP))
                {
                    AppendLineToChatHistory("Connection mode has been changed. Any existing connections will be closed.");
                    NetworkComms.Shutdown();
                }
                else
                {
                    AppendLineToChatHistory("Enabling local server mode. Any existing connections will be closed.");
                    NetworkComms.Shutdown();
                }

                //Start listening for new incoming UDP connections
                //We want to select a random port on all available adaptors so provide
                //an IPEndPoint using IPAddress.Any and port 0.
                Connection.StartListening(ConnectionType.UDP, new IPEndPoint(IPAddress.Any, 0));

                //Write the IP addresses and ports that we are listening on to the chatBox
                AppendLineToChatHistory("Listening for incoming UDP connections on:");
                foreach (IPEndPoint listenEndPoint in Connection.ExistingLocalListenEndPoints(ConnectionType.UDP))
                {
                    AppendLineToChatHistory(listenEndPoint.Address + ":" + listenEndPoint.Port);
                }

                //Add a blank line after the initialisation output
                AppendLineToChatHistory(System.Environment.NewLine);
            }
            else if (!LocalServerEnabled && (Connection.Listening(ConnectionType.TCP) || Connection.Listening(ConnectionType.UDP)))
            {
                //If the local server mode has been disabled but we are still listening we need to stop accepting incoming connections
                NetworkComms.Shutdown();
                AppendLineToChatHistory("Local server mode disabled. Any existing connections will be closed.");
                AppendLineToChatHistory(System.Environment.NewLine);
            }
            else if (!LocalServerEnabled &&
                     ((ConnectionType == ConnectionType.UDP && NetworkComms.GetExistingConnection(ConnectionType.TCP).Count > 0) ||
                      (ConnectionType == ConnectionType.TCP && NetworkComms.GetExistingConnection(ConnectionType.UDP).Count > 0)))
            {
                //If we are not running a local server but have changed the connection type after creating connections we need to close
                //existing connections.
                NetworkComms.Shutdown();
                AppendLineToChatHistory("Connection mode has been changed. Existing connections will be closed.");
                AppendLineToChatHistory(System.Environment.NewLine);
            }
            #endregion
        }