public void Listen() { NetworkComms.AppendGlobalIncomingPacketHandler <string>("Message", ReadIncommingCommand); Console.WriteLine("Server is waiting for new connection. To close server press 'C' "); }
public void Connect(string hostIp, int hostPort) { this.HostIp = hostIp; this.HostPort = hostPort; NetworkComms.AppendGlobalIncomingPacketHandler <Command>("Command", ProcessCommand); }
/// <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 receive 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 }
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { //Ensure we shutdown comms when we are finished NetworkComms.Shutdown(); }
private void OnDestroy() { NetworkComms.Shutdown(); }
public void StopServer() { _Server.ServerInfo -= _Server_ServerInfo; NetworkComms.Shutdown(); Log("======= Network Shutdown ======= ", MServer.UTILITY); }
private static void errorHandler(PacketHeader header, Connection connection, string message) { Console.WriteLine("KO"); NetworkComms.Shutdown(); System.Environment.Exit(84); }
internal static void Shutdown() { NetworkComms.Shutdown(); }
/// <summary> /// Run the example /// </summary> public void Run() { //Expecting user to enter ip address as 192.168.0.1:4000 ConnectionInfo connectionInfo = ExampleHelper.GetServerDetails(); SelectConnectionType(); try { //We would really like to create a local instance of MathClass, but the client does not have a //reference to MathClass (defined server side only): // //IMath remoteObject = new MathClass(); // //This example is all about RPC, so we create the instance remotely instead, as follows ... //We need to select our remote object using one of the available access methods string instanceId = ""; Connection connection = null; if (connectionTypeToUse == ConnectionType.TCP) { connection = TCPConnection.GetConnection(connectionInfo); } else { connection = UDPConnection.GetConnection(connectionInfo, UDPOptions.None); } //Get the remote object IMath remoteObject = SelectRemoteObject(connection, out instanceId); //Add a handler to the object's event to demonstrate remote triggering of events remoteObject.EchoEvent += (sender, args) => { Console.WriteLine("Echo event received saying {0}", args.EchoValue); }; Console.WriteLine("\nRemote object has been selected. RPC object instanceId: {0}", instanceId); while (true) { //We can now perform RPC operations on our remote object Console.WriteLine("\nPlease press 'y' key to perform some remote math. Any other key will quit the example."); string message = Console.ReadKey(true).KeyChar.ToString().ToLower(); //If the user has typed exit then we leave our loop and end the example if (message == "y") { //We pass our remoteObject to our local method DoMath to keep this area of code clean Console.WriteLine("Result: " + DoMath(remoteObject).ToString()); } else { break; } } } catch (Exception e) { Console.WriteLine(e.ToString()); } finally { NetworkComms.Shutdown(); } }
/// <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 mode Console.WriteLine("Distributed File System (DFS) Example ...\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; } 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", "exampleItem", new MemoryStream(someRandomData), seedConnectionInfoList, DataBuildMode.Disk_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."); ConnectionInfo serverConnectionInfo = ExampleHelper.GetServerDetails(); 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; } catch (Exception) { 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); } 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); #endregion } DFS.Shutdown(); NetworkComms.Shutdown(); }
/// <summary> /// Closes the connection and trigger any associated shutdown delegates. /// </summary> /// <param name="closeDueToError">Closing a connection due an error possibly requires a few extra steps.</param> /// <param name="logLocation">Optional debug parameter.</param> public void CloseConnection(bool closeDueToError, int logLocation = 0) { try { if (NetworkComms.LoggingEnabled) { if (closeDueToError) { NetworkComms.Logger.Debug("Closing connection with " + ConnectionInfo + " due to error from [" + logLocation.ToString() + "]."); } else { NetworkComms.Logger.Debug("Closing connection with " + ConnectionInfo + " from [" + logLocation.ToString() + "]."); } } ConnectionInfo.NoteConnectionShutdown(); //Set possible error cases if (closeDueToError) { connectionSetupException = true; connectionSetupExceptionStr = "Connection was closed during setup from [" + logLocation.ToString() + "]."; } //Ensure we are not waiting for a connection to be established if we have died due to error connectionSetupWait.Set(); //Call any connection specific close requirements CloseConnectionSpecific(closeDueToError, logLocation); #if !NETFX_CORE try { //If we are calling close from the listen thread we are actually in the same thread //We must guarantee the listen thread stops even if that means we need to nuke it //If we did not we may not be able to shutdown properly. if (incomingDataListenThread != null && incomingDataListenThread != Thread.CurrentThread && (incomingDataListenThread.ThreadState == System.Threading.ThreadState.WaitSleepJoin || incomingDataListenThread.ThreadState == System.Threading.ThreadState.Running)) { //If we have made it this far we give the thread a further 50ms to finish before nuking. if (!incomingDataListenThread.Join(50)) { incomingDataListenThread.Abort(); if (NetworkComms.LoggingEnabled && ConnectionInfo != null) { NetworkComms.Logger.Warn("Incoming data listen thread with " + ConnectionInfo + " aborted."); } } } } catch (Exception) { } #endif //Close connection my get called multiple times for a given connection depending on the reason for being closed bool firstClose = NetworkComms.RemoveConnectionReference(this); try { //Almost there //Last thing is to call any connection specific shutdown delegates if (firstClose && 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 (firstClose && 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."); } } catch (Exception ex) { #if !NETFX_CORE if (ex is ThreadAbortException) { /*Ignore the threadabort exception if we had to nuke a thread*/ } else #endif LogTools.LogException(ex, "NCError_CloseConnection", "Error closing connection with " + ConnectionInfo + ". Close called from " + logLocation.ToString() + (closeDueToError ? " due to error." : ".")); //We try to rethrow where possible but CloseConnection could very likely be called from within networkComms so we just have to be happy with a log here } }
public override void InitializePacket() { NetworkComms.AppendGlobalIncomingPacketHandler <WritingStatus>(PacketName.sendWritingStatus.ToString(), Status); }
/// <summary> /// closes the communication /// </summary> public void ShutDown() { //We have used NetworkComms so we should ensure that we correctly call shutdown NetworkComms.Shutdown(); }
public ClientMsgHandler(Connection connection) { _tcPcon = connection; NetworkComms.AppendGlobalIncomingPacketHandler <Protocol>("Protocol", TreatMsgFromServer); }
/// <summary> /// Internal <see cref="BluetoothConnection"/> 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="btClient">If this is an incoming connection we will already have access to the btClient, otherwise use null</param> /// <param name="establishIfRequired">Establish during create if true</param> /// <returns>An existing connection or a new one</returns> internal static BluetoothConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, BluetoothClient btClient, bool establishIfRequired = true) { connectionInfo.ConnectionType = ConnectionType.Bluetooth; //If we have a tcpClient at this stage we must be server side if (btClient != null) { connectionInfo.ServerSide = true; } bool newConnection = false; BluetoothConnection connection; lock (NetworkComms.globalDictAndDelegateLocker) { List <Connection> existingConnections = NetworkComms.GetExistingConnection(connectionInfo.RemoteEndPoint, connectionInfo.LocalEndPoint, 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 BluetoothConnection to connectionInfo='" + connectionInfo + "' but there is an existing connection. Existing connection will be returned instead."); } establishIfRequired = false; connection = (BluetoothConnection)existingConnections[0]; } else { if (NetworkComms.LoggingEnabled) { NetworkComms.Logger.Trace("Creating new BluetoothConnection 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 NetworkComms.Net 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 connection = new BluetoothConnection(connectionInfo, defaultSendReceiveOptions, btClient); newConnection = true; } } if (newConnection && establishIfRequired) { connection.EstablishConnection(); } else if (!newConnection) { connection.WaitForConnectionEstablish(NetworkComms.ConnectionEstablishTimeoutMS); } if (!NetworkComms.commsShutdown) { TriggerConnectionKeepAliveThread(); } return(connection); }
private void MsgForm_FormClosing(object sender, FormClosingEventArgs e) { NetworkComms.Shutdown(); this.Dispose(); this.Close(); }
public override void InitializePacket() { NetworkComms.AppendGlobalIncomingPacketHandler <UserInfo>(PacketName.sendContactDelete.ToString(), IncomingDeleteContact); }
//Spojení se serverem ztraceno private void ConnectionShutdownDelegate(Connection connection) { MessageBox.Show($"Spojení se serverem {ServerName} ztraceno!"); NetworkComms.Shutdown(); Application.Exit(); }
void initCallbacks() { NetworkComms.AppendGlobalIncomingPacketHandler <string>("200", confirmationHandler); NetworkComms.AppendGlobalIncomingPacketHandler <string>("500", errorHandler); NetworkComms.AppendGlobalIncomingPacketHandler <Player>("Start", startGame); }
/// <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); } }
/// <summary> /// Returns the <see cref="SendReceiveOptions"/> to be used for the provided <see cref="PacketHeader"/>. Ensures there /// will not be a serializer or data processor clash for different delegate levels. /// </summary> /// <param name="header">The <see cref="PacketHeader"/> options are desired.</param> /// <returns>The requested <see cref="SendReceiveOptions"/></returns> internal SendReceiveOptions IncomingPacketSendReceiveOptions(PacketHeader header) { //Are there connection specific or global packet handlers? bool connectionSpecificHandlers = false; lock (_syncRoot) connectionSpecificHandlers = incomingPacketHandlers.ContainsKey(header.PacketType); bool globalHandlers = NetworkComms.GlobalIncomingPacketHandlerExists(header.PacketType); //Get connection specific options for this packet type, if there aren't any use the connection default options SendReceiveOptions connectionSpecificOptions = PacketTypeUnwrapperOptions(header.PacketType); if (connectionSpecificOptions == null) { connectionSpecificOptions = ConnectionDefaultSendReceiveOptions; } //Get global options for this packet type, if there aren't any use the global default options SendReceiveOptions globalOptions = NetworkComms.GlobalPacketTypeUnwrapperOptions(header.PacketType); if (globalOptions == null) { globalOptions = NetworkComms.DefaultSendReceiveOptions; } if (connectionSpecificHandlers && globalHandlers) { if (!connectionSpecificOptions.OptionsCompatible(globalOptions)) { throw new PacketHandlerException("Attempted to determine correct sendReceiveOptions for packet of type '" + header.PacketType + "'. Unable to continue as connection specific and global sendReceiveOptions are not equal."); } //We need to combine options in this case using the connection specific option in preference if both are present var combinedOptions = new Dictionary <string, string>(globalOptions.Options); foreach (var pair in connectionSpecificOptions.Options) { combinedOptions[pair.Key] = pair.Value; } //If the header specifies a serializer and data processors we will auto detect those if (header.ContainsOption(PacketHeaderLongItems.SerializerProcessors)) { DataSerializer serializer; List <DataProcessor> dataProcessors; DPSManager.GetSerializerDataProcessorsFromIdentifier(header.GetOption(PacketHeaderLongItems.SerializerProcessors), out serializer, out dataProcessors); return(new SendReceiveOptions(serializer, dataProcessors, combinedOptions)); } //Otherwise we will use options that were specified return(new SendReceiveOptions(connectionSpecificOptions.DataSerializer, connectionSpecificOptions.DataProcessors, combinedOptions)); } ////////////////////////////////////////////// //// Changed 20/05/14 to fix bug when encryption options is set on the listener and not the packet handler ////////////////////////////////////////////// else //if (connectionSpecificHandlers) { //If the header specifies a serializer and data processors we will auto detect those if (header.ContainsOption(PacketHeaderLongItems.SerializerProcessors)) { DataSerializer serializer; List <DataProcessor> dataProcessors; DPSManager.GetSerializerDataProcessorsFromIdentifier(header.GetOption(PacketHeaderLongItems.SerializerProcessors), out serializer, out dataProcessors); return(new SendReceiveOptions(serializer, dataProcessors, connectionSpecificOptions.Options)); } return(connectionSpecificOptions); } //else //{ // //If the header specifies a serializer and data processors we will auto detect those // if (header.ContainsOption(PacketHeaderLongItems.SerializerProcessors)) // { // DataSerializer serializer; // List<DataProcessor> dataProcessors; // DPSManager.GetSerializerDataProcessorsFromIdentifier(header.GetOption(PacketHeaderLongItems.SerializerProcessors), out serializer, out dataProcessors); // return new SendReceiveOptions(serializer, dataProcessors, globalOptions.Options); // } // //If just globalHandlers is set (or indeed no handlers at all we just return the global options // return globalOptions; //} }
/// <summary> /// Closes the connection with the server. /// </summary> public void DisconnectFromServer() { this.MyConnection?.CloseConnection(false); NetworkComms.Shutdown(); }
/// <summary> /// Polls all existing connections based on ConnectionKeepAlivePollIntervalSecs value. Server side connections are polled /// slightly earlier than client side to help reduce potential congestion. /// </summary> /// <param name="returnImmediately">If true runs as task and returns immediately.</param> private static void AllConnectionsSendNullPacketKeepAlive(bool returnImmediately = false) { if (NetworkComms.LoggingEnabled) { NetworkComms.Logger.Trace("Starting AllConnectionsSendNullPacketKeepAlive"); } //Loop through all connections and test the alive state List <Connection> allConnections = NetworkComms.GetExistingConnection(ApplicationLayerProtocolStatus.Enabled); int remainingConnectionCount = allConnections.Count; QueueItemPriority nullSendPriority = QueueItemPriority.AboveNormal; ManualResetEvent allConnectionsComplete = new ManualResetEvent(false); for (int i = 0; i < allConnections.Count; i++) { //We don't send null packets to unconnected UDP connections UDPConnection asUDP = allConnections[i] as UDPConnection; if (asUDP != null && asUDP.ConnectionUDPOptions == UDPOptions.None) { if (Interlocked.Decrement(ref remainingConnectionCount) == 0) { allConnectionsComplete.Set(); } continue; } else { int innerIndex = i; NetworkComms.CommsThreadPool.EnqueueItem(nullSendPriority, new WaitCallback((obj) => { try { //If the connection is server side we poll preferentially if (allConnections[innerIndex] != null) { if (allConnections[innerIndex].ConnectionInfo.ServerSide) { //We check the last incoming traffic time //In scenarios where the client is sending us lots of data there is no need to poll if ((DateTime.Now - allConnections[innerIndex].ConnectionInfo.LastTrafficTime).TotalSeconds > ConnectionKeepAlivePollIntervalSecs) { allConnections[innerIndex].SendNullPacket(); } } else { //If we are client side we wait up to an additional 3 seconds to do the poll //This means the server will probably beat us if ((DateTime.Now - allConnections[innerIndex].ConnectionInfo.LastTrafficTime).TotalSeconds > ConnectionKeepAlivePollIntervalSecs + 1.0 + (NetworkComms.randomGen.NextDouble() * 2.0)) { allConnections[innerIndex].SendNullPacket(); } } } } catch (Exception) { } finally { if (Interlocked.Decrement(ref remainingConnectionCount) == 0) { allConnectionsComplete.Set(); } } }), null); } } //Max wait is 1 seconds per connection if (!returnImmediately && allConnections.Count > 0) { #if NET2 if (!allConnectionsComplete.WaitOne(allConnections.Count * 2500, false)) #else if (!allConnectionsComplete.WaitOne(allConnections.Count * 2500)) #endif { //This timeout should not really happen so we are going to log an error if it does //LogTools.LogException(new TimeoutException("Timeout after " + allConnections.Count.ToString() + " seconds waiting for null packet sends to finish. " + remainingConnectionCount.ToString() + " connection waits remain. This error indicates very high send load or a possible send deadlock."), "NullPacketKeepAliveTimeoutError"); if (NetworkComms.LoggingEnabled) { NetworkComms.Logger.Warn("Timeout after " + allConnections.Count.ToString() + " seconds waiting for null packet sends to finish. " + remainingConnectionCount.ToString() + " connection waits remain. This error indicates very high send load or a possible send deadlock."); } } } }
/// <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="existingConnection"></param> /// <returns></returns> internal static UDPConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, UDPOptions level, bool listenForReturnPackets, UDPConnection existingConnection) { connectionInfo.ConnectionType = ConnectionType.UDP; UDPConnection connection = null; lock (NetworkComms.globalDictAndDelegateLocker) { if (NetworkComms.ConnectionExists(connectionInfo.RemoteEndPoint, ConnectionType.UDP)) { connection = (UDPConnection)NetworkComms.GetExistingConnection(connectionInfo.RemoteEndPoint, ConnectionType.UDP); } 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 (existingConnection == null) { try { IPEndPoint localEndPoint = NetworkComms.BestLocalEndPoint(connectionInfo.RemoteEndPoint); lock (udpClientListenerLocker) { IPEndPoint existingLocalEndPoint = ExistingLocalListenEndPoints(localEndPoint.Address); if (existingLocalEndPoint != null) { existingConnection = udpConnectionListeners[existingLocalEndPoint]; //If we are using an existing listener there is no need to listen for packets listenForReturnPackets = false; } } } catch (Exception) { if (NetworkComms.LoggingEnabled) { NetworkComms.Logger.Trace("Failed to determine preferred existing udpClientListener to " + connectionInfo.RemoteEndPoint.Address + ":" + connectionInfo.RemoteEndPoint.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, existingConnection); } } if (!NetworkComms.commsShutdown) { TriggerConnectionKeepAliveThread(); } return(connection); }
public void PushCommand(Command cmd) { NetworkComms.SendObject("Command", this.HostIp, this.HostPort, cmd); }
/// <summary> /// Sends a single object to the provided endPoint. NOTE: Any possible reply will be ignored unless listening for incoming udp packets. /// </summary> /// <param name="sendingPacketType">The sending packet type</param> /// <param name="objectToSend">The object to send</param> /// <param name="ipEndPoint">The destination IPEndPoint. Supports multicast endpoints.</param> /// <param name="sendReceiveOptions">The sendReceiveOptions to use for this send</param> public static void SendObject(string sendingPacketType, object objectToSend, IPEndPoint ipEndPoint, SendReceiveOptions sendReceiveOptions) { UDPConnection connectionToUse; 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(ipEndPoint.AddressFamily) || udpRogueSenders[ipEndPoint.AddressFamily].ConnectionInfo.ConnectionState == ConnectionState.Shutdown) { if (NetworkComms.LoggingEnabled) { NetworkComms.Logger.Trace("Creating UDPRougeSender."); } IPAddress any; if (ipEndPoint.AddressFamily == AddressFamily.InterNetwork) { any = IPAddress.Any; } else if (ipEndPoint.AddressFamily == AddressFamily.InterNetworkV6) { any = IPAddress.IPv6Any; } else { throw new CommunicationException("Attempting to send UDP packet over unsupported network address family: " + ipEndPoint.AddressFamily.ToString()); } udpRogueSenders[ipEndPoint.AddressFamily] = new UDPConnection(new ConnectionInfo(true, ConnectionType.UDP, new IPEndPoint(any, 0), new IPEndPoint(any, 0)), NetworkComms.DefaultSendReceiveOptions, UDPOptions.None, false); } //Get the rouge sender here connectionToUse = udpRogueSenders[ipEndPoint.AddressFamily]; } //Get connection defaults if no sendReceiveOptions were provided if (sendReceiveOptions == null) { sendReceiveOptions = connectionToUse.ConnectionDefaultSendReceiveOptions; } //If we are listening on what will be the outgoing adaptor we send with that client to ensure reply packets are collected //Determining this is annoyingly non-trivial //For now we will use the following method and look to improve upon it in future //Some very quick testing gave an average runtime of this method to be 0.12ms (averageover 1000 iterations) (perhaps not so bad after all) try { IPEndPoint localEndPoint = NetworkComms.BestLocalEndPoint(ipEndPoint); lock (udpClientListenerLocker) { IPEndPoint existingLocalEndPoint = ExistingLocalListenEndPoints(localEndPoint.Address); if (existingLocalEndPoint != null) { connectionToUse = udpConnectionListeners[existingLocalEndPoint]; } } } catch (Exception ex) { //if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace("Failed to determine preferred existing udpClientListener to " + ipEndPoint.Address + ":" + ipEndPoint.Port + ". Will just use the rogue udp sender instead."); NetworkComms.LogError(ex, "BestLocalEndPointError"); } using (Packet sendPacket = new Packet(sendingPacketType, objectToSend, sendReceiveOptions)) connectionToUse.SendPacketSpecific(sendPacket, ipEndPoint); }
public void LoadPlugins() { this.Log.Info("Entered LoadPlugins"); var types = PluginFinder.FindPlugins(); this.Log.Info("Loading Plugins"); foreach (var type in types) { this.Log.Debug("type.TypeName: " + type.TypeName); this.Log.Debug("type.AssemblyName: " + type.AssemblyName); var domain = Common.CreateSandboxDomain("Sandbox Domain", type.Location, SecurityZone.Internet, typeof(ClientService)); plugins.Add(new Plugin(type.AssemblyName, type.TypeName, domain, type.Location)); } this.Log.Info("Found " + plugins.Count.ToString() + " plugins"); foreach (Plugin plugin in plugins) { try { this.Log.Info("---------------------------------------"); this.Log.Info("plugin name: " + plugin.PluginName); this.Log.Info("plugin type: " + plugin.PluginType); if (plugin.PluginName != string.Empty) { OSAEObject obj = OSAEObjectManager.GetObjectByName(plugin.PluginName); this.Log.Info("setting found: " + obj.Name + " - " + obj.Enabled.ToString()); bool isSystemPlugin = false; foreach (OSAEObjectProperty p in obj.Properties) { if (p.Name == "System Plugin") { if (p.Value == "TRUE") { isSystemPlugin = true; } break; } } this.Log.Info("isSystemPlugin?: " + isSystemPlugin.ToString()); if (!isSystemPlugin) { if (obj.Enabled == 1) { try { enablePlugin(plugin); } catch (Exception ex) { this.Log.Error("Error activating plugin (" + plugin.PluginName + ")", ex); } } else { plugin.Enabled = false; } this.Log.Info("status: " + plugin.Enabled.ToString()); this.Log.Info("PluginName: " + plugin.PluginName); this.Log.Info("PluginVersion: " + plugin.PluginVersion); NetworkComms.SendObject("Plugin", Common.WcfServer, 10000, plugin.PluginName + "|" + plugin.Status + "|" + plugin.PluginVersion + "|" + plugin.Enabled); } } else { //add code to create the object. We need the plugin to specify the type though this.Log.Info("Plugin object doesn't exist"); DataSet dataset = OSAESql.RunSQL("SELECT * FROM osae_object_type_property p inner join osae_object_type t on p.object_type_id = t.object_type_id WHERE object_type='" + plugin.PluginType + "' AND property_name='Computer Name'"); this.Log.Info("dataset count: " + dataset.Tables[0].Rows.Count.ToString()); // if object type has a property called 'Computer Name' we know it is not a System Plugin if (dataset.Tables[0].Rows.Count > 0) { plugin.PluginName = plugin.PluginType + "-" + Common.ComputerName; this.Log.Info("Plugin object does not exist in DB: " + plugin.PluginName); OSAEObjectManager.ObjectAdd(plugin.PluginName, plugin.PluginName, plugin.PluginType, "", "System", false); OSAEObjectPropertyManager.ObjectPropertySet(plugin.PluginName, "Computer Name", Common.ComputerName, "Client Service"); this.Log.Info("Plugin added to DB: " + plugin.PluginName); NetworkComms.SendObject("Plugin", Common.WcfServer, 10000, plugin.PluginName + "|" + plugin.Status + "|" + plugin.PluginVersion + "|" + plugin.Enabled); } } } catch (Exception ex) { this.Log.Error("Error loading plugin", ex); } } this.Log.Info("Done loading plugins"); }
public ServerMsgHandler(List <Player> playerlist, GameHandler game) { _game = game; _playerList = playerlist; NetworkComms.AppendGlobalIncomingPacketHandler <Protocol>("Protocol", TreatPacketFromClient); }
/// <summary> /// Send a message. /// </summary> public void SendMessage(string stringToSend) { //If we have tried to send a zero length string we just return if (stringToSend.Trim() == "") { return; } //We may or may not have entered some server connection information ConnectionInfo serverConnectionInfo = null; if (ServerIPAddress != "") { try { serverConnectionInfo = new ConnectionInfo(ServerIPAddress, ServerPort); } catch (Exception) { ShowMessage("Failed to parse the server IP and port. Please ensure it is correct and try again"); return; } } //We wrap everything we want to send in the ChatMessage class we created ChatMessage chatMessage = new ChatMessage(NetworkComms.NetworkIdentifier, LocalName, stringToSend, messageSendIndex++); //We add our own message to the message history in case it gets relayed back to us lock (lastPeerMessageDict) lastPeerMessageDict[NetworkComms.NetworkIdentifier] = chatMessage; //We write our own message to the chatBox AppendLineToChatHistory(chatMessage.SourceName + " - " + chatMessage.Message); //Clear the input box text ClearInputLine(); //If we provided server information we send to the server first if (serverConnectionInfo != null) { //We perform the send within a try catch to ensure the application continues to run if there is a problem. try { if (ConnectionType == ConnectionType.TCP) { TCPConnection.GetConnection(serverConnectionInfo).SendObject("ChatMessage", chatMessage); } else if (ConnectionType == ConnectionType.UDP) { UDPConnection.GetConnection(serverConnectionInfo, UDPOptions.None).SendObject("ChatMessage", chatMessage); } else { throw new Exception("An invalid connectionType is set."); } } catch (CommsException) { AppendLineToChatHistory("Error: A communication error occurred while trying to send message to " + serverConnectionInfo + ". Please check settings and try again."); } catch (Exception) { AppendLineToChatHistory("Error: A general error occurred while trying to send message to " + serverConnectionInfo + ". Please check settings and try again."); } } //If we have any other connections we now send the message to those as well //This ensures that if we are the server everyone who is connected to us gets our message //We want a list of all established connections not including the server if set List <ConnectionInfo> otherConnectionInfos; if (serverConnectionInfo != null) { otherConnectionInfos = (from current in NetworkComms.AllConnectionInfo() where current.RemoteEndPoint != serverConnectionInfo.RemoteEndPoint select current).ToList(); } else { otherConnectionInfos = NetworkComms.AllConnectionInfo(); } foreach (ConnectionInfo info in otherConnectionInfos) { //We perform the send within a try catch to ensure the application continues to run if there is a problem. try { if (ConnectionType == ConnectionType.TCP) { TCPConnection.GetConnection(info).SendObject("ChatMessage", chatMessage); } else if (ConnectionType == ConnectionType.UDP) { UDPConnection.GetConnection(info, UDPOptions.None).SendObject("ChatMessage", chatMessage); } else { throw new Exception("An invalid connectionType is set."); } } catch (CommsException) { AppendLineToChatHistory("Error: A communication error occurred while trying to send message to " + info + ". Please check settings and try again."); } catch (Exception) { AppendLineToChatHistory("Error: A general error occurred while trying to send message to " + info + ". Please check settings and try again."); } } return; }
public void CloseServer() { mySqlDao.CloseConnection(); NetworkComms.Shutdown(); }