/// <summary> /// Broadcast text from server to all connected clients /// </summary> /// <param name="text"></param> public void BroadcastText(string text) { CCriticalSection CCBroadcast = new CCriticalSection(); CCBroadcast.Enter(); try { if (ConnectedClientsIndexes.Count > 0) { byte[] b = Encoding.GetEncoding(28591).GetBytes(text); foreach (uint i in ConnectedClientsIndexes) { if (!SharedKeyRequired || (SharedKeyRequired && ClientReadyAfterKeyExchange.Contains(i))) { SocketErrorCodes error = SecureServer.SendDataAsync(i, b, b.Length, (x, y, z) => { }); if (error != SocketErrorCodes.SOCKET_OK && error != SocketErrorCodes.SOCKET_OPERATION_PENDING) { Debug.Console(2, error.ToString()); } } } } CCBroadcast.Leave(); } catch (Exception ex) { CCBroadcast.Leave(); Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error Broadcasting messages from server. Error: {0}", ex.Message); } }
public void ServerDataReceivedCallback(SecureTCPServer server, uint clientIndex, int bytesReceived) { if (bytesReceived <= 0) { CrestronConsole.PrintLine("ServerDataReceivedCallback error: server's connection with client " + clientIndex + " has been closed."); server.Disconnect(clientIndex); // A connection has closed, so another client may connect if the server stopped listening // due to the maximum number of clients connecting if ((server.State & ServerState.SERVER_NOT_LISTENING) > 0) { server.WaitForConnectionAsync(ServerConnectedCallback); } } else { CrestronConsole.PrintLine("\n------ incoming message -----------"); byte[] recvd_bytes = new byte[bytesReceived]; // Copy the received bytes into a local buffer so that they can be echoed back. // Do not pass the reference to the incoming data buffer itself to the SendDataAsync method Array.Copy(server.GetIncomingDataBufferForSpecificClient(clientIndex), recvd_bytes, bytesReceived); // The server in this example expects ASCII text from the client, but any other encoding is possible string recvd_msg = ASCIIEncoding.ASCII.GetString(recvd_bytes, 0, bytesReceived); CrestronConsole.PrintLine("Client " + clientIndex + " says: " + recvd_msg + "\r\nEchoing back to client " + clientIndex + "..."); // echo the received message back to the client who sent it server.SendDataAsync(clientIndex, recvd_bytes, recvd_bytes.Length, ServerDataSentCallback); // Begin waiting for another message from that same client server.ReceiveDataAsync(clientIndex, ServerDataReceivedCallback); CrestronConsole.PrintLine("---------- end of message ----------"); } }
/// <summary> /// Secure Received Data Async Callback /// </summary> /// <param name="mySecureTCPServer"></param> /// <param name="clientIndex"></param> /// <param name="numberOfBytesReceived"></param> void SecureReceivedDataAsyncCallback(SecureTCPServer mySecureTCPServer, uint clientIndex, int numberOfBytesReceived) { if (numberOfBytesReceived > 0) { string received = "Nothing"; byte[] bytes = mySecureTCPServer.GetIncomingDataBufferForSpecificClient(clientIndex); received = System.Text.Encoding.GetEncoding(28591).GetString(bytes, 0, numberOfBytesReceived); if (WaitingForSharedKey.Contains(clientIndex)) { received = received.Replace("\r", ""); received = received.Replace("\n", ""); if (received != SharedKey) { byte[] b = Encoding.GetEncoding(28591).GetBytes("Shared key did not match server. Disconnecting"); Debug.Console(2, "Client at index {0} Shared key did not match the server, disconnecting client", clientIndex); ErrorLog.Error("Client at index {0} Shared key did not match the server, disconnecting client", clientIndex); mySecureTCPServer.SendDataAsync(clientIndex, b, b.Length, null); mySecureTCPServer.Disconnect(clientIndex); } if (mySecureTCPServer.NumberOfClientsConnected > 0) { mySecureTCPServer.ReceiveDataAsync(SecureReceivedDataAsyncCallback); } WaitingForSharedKey.Remove(clientIndex); byte[] skResponse = Encoding.GetEncoding(28591).GetBytes("Shared Key Match, Connected and ready for communication"); mySecureTCPServer.SendDataAsync(clientIndex, skResponse, skResponse.Length, null); mySecureTCPServer.ReceiveDataAsync(SecureReceivedDataAsyncCallback); } else { mySecureTCPServer.ReceiveDataAsync(SecureReceivedDataAsyncCallback); Debug.Console(2, "Secure Server Listening on Port: {0}, client IP: {1}, NumberOfBytesReceived: {2}, Received: {3}\r\n", mySecureTCPServer.PortNumber, mySecureTCPServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex), numberOfBytesReceived, received); onTextReceived(received); } checkHeartbeat(clientIndex, received); } if (mySecureTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED) { mySecureTCPServer.ReceiveDataAsync(clientIndex, SecureReceivedDataAsyncCallback); } }
/// <summary> /// Broadcast text from server to all connected clients /// </summary> /// <param name="text"></param> public void BroadcastText(string text) { if (ConnectedClientsIndexes.Count > 0) { byte[] b = Encoding.GetEncoding(28591).GetBytes(text); if (Secure) { foreach (uint i in ConnectedClientsIndexes) { SecureServer.SendDataAsync(i, b, b.Length, SecureSendDataAsyncCallback); } } else { foreach (uint i in ConnectedClientsIndexes) { UnsecureServer.SendDataAsync(i, b, b.Length, UnsecureSendDataAsyncCallback); } } } }
/// <summary> /// Secure TCP Client Connected to Secure Server Callback /// </summary> /// <param name="mySecureTCPServer"></param> /// <param name="clientIndex"></param> void SecureConnectCallback(SecureTCPServer mySecureTCPServer, uint clientIndex) { if (mySecureTCPServer.ClientConnected(clientIndex)) { if (SharedKeyRequired) { byte[] b = Encoding.GetEncoding(28591).GetBytes(SharedKey + "\n"); mySecureTCPServer.SendDataAsync(clientIndex, b, b.Length, SecureSendDataAsyncCallback); Debug.Console(2, "Sent Shared Key to client at {0}", mySecureTCPServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex)); } if (HeartbeatRequired) { CTimer HeartbeatTimer = new CTimer(HeartbeatTimer_CallbackFunction, clientIndex, HeartbeatRequiredIntervalMs); HeartbeatTimerDictionary.Add(clientIndex, HeartbeatTimer); } mySecureTCPServer.ReceiveDataAsync(clientIndex, SecureReceivedDataAsyncCallback); if (mySecureTCPServer.State != ServerState.SERVER_LISTENING && MaxClients > 1 && !ServerStopped) { mySecureTCPServer.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback); } } }
/// <summary> /// Secure Received Data Async Callback /// </summary> /// <param name="mySecureTCPServer"></param> /// <param name="clientIndex"></param> /// <param name="numberOfBytesReceived"></param> void SecureReceivedDataAsyncCallback(SecureTCPServer mySecureTCPServer, uint clientIndex, int numberOfBytesReceived) { if (numberOfBytesReceived > 0) { string received = "Nothing"; var handler = TextReceivedQueueInvoke; try { byte[] bytes = mySecureTCPServer.GetIncomingDataBufferForSpecificClient(clientIndex); received = System.Text.Encoding.GetEncoding(28591).GetString(bytes, 0, numberOfBytesReceived); if (WaitingForSharedKey.Contains(clientIndex)) { received = received.Replace("\r", ""); received = received.Replace("\n", ""); if (received != SharedKey) { byte[] b = Encoding.GetEncoding(28591).GetBytes("Shared key did not match server. Disconnecting"); Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Client at index {0} Shared key did not match the server, disconnecting client. Key: {1}", clientIndex, received); mySecureTCPServer.SendData(clientIndex, b, b.Length); mySecureTCPServer.Disconnect(clientIndex); return; } WaitingForSharedKey.Remove(clientIndex); byte[] success = Encoding.GetEncoding(28591).GetBytes("Shared Key Match"); mySecureTCPServer.SendDataAsync(clientIndex, success, success.Length, null); OnServerClientReadyForCommunications(clientIndex); Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Client with index {0} provided the shared key and successfully connected to the server", clientIndex); } else if (!string.IsNullOrEmpty(checkHeartbeat(clientIndex, received))) { onTextReceived(received, clientIndex); if (handler != null) { MessageQueue.TryToEnqueue(new GenericTcpServerCommMethodReceiveTextArgs(received, clientIndex)); } } } catch (Exception ex) { Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error Receiving data: {0}. Error: {1}", received, ex); } if (mySecureTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED) { mySecureTCPServer.ReceiveDataAsync(clientIndex, SecureReceivedDataAsyncCallback); } //Check to see if there is a subscription to the TextReceivedQueueInvoke event. If there is start the dequeue thread. if (handler != null) { var gotLock = DequeueLock.TryEnter(); if (gotLock) { CrestronInvoke.BeginInvoke((o) => DequeueEvent()); } } } else { mySecureTCPServer.Disconnect(clientIndex); } }
/// <summary> /// Secure TCP Client Connected to Secure Server Callback /// </summary> /// <param name="mySecureTCPServer"></param> /// <param name="clientIndex"></param> void SecureConnectCallback(SecureTCPServer server, uint clientIndex) { try { Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "ConnectCallback: IPAddress: {0}. Index: {1}. Status: {2}", server.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex), clientIndex, server.GetServerSocketStatusForSpecificClient(clientIndex)); if (clientIndex != 0) { if (server.ClientConnected(clientIndex)) { if (!ConnectedClientsIndexes.Contains(clientIndex)) { ConnectedClientsIndexes.Add(clientIndex); } if (SharedKeyRequired) { if (!WaitingForSharedKey.Contains(clientIndex)) { WaitingForSharedKey.Add(clientIndex); } byte[] b = Encoding.GetEncoding(28591).GetBytes("SharedKey:"); server.SendDataAsync(clientIndex, b, b.Length, (x, y, z) => { }); Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Sent Shared Key Request to client at {0}", server.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex)); } else { OnServerClientReadyForCommunications(clientIndex); } if (HeartbeatRequired) { if (!HeartbeatTimerDictionary.ContainsKey(clientIndex)) { HeartbeatTimerDictionary.Add(clientIndex, new CTimer(HeartbeatTimer_CallbackFunction, clientIndex, HeartbeatRequiredIntervalMs)); } } server.ReceiveDataAsync(clientIndex, SecureReceivedDataAsyncCallback); } } else { Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Client attempt faulty."); } } catch (Exception ex) { Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error in Socket Status Connect Callback. Error: {0}", ex); } // Rearm the listner SocketErrorCodes status = server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback); if (status != SocketErrorCodes.SOCKET_OPERATION_PENDING) { Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Socket status connect callback status {0}", status); if (status == SocketErrorCodes.SOCKET_CONNECTION_IN_PROGRESS) { // There is an issue where on a failed negotiation we need to stop and start the server. This should still leave connected clients intact. server.Stop(); Listen(); } } }
/// <summary> /// Secure TCP Client Connected to Secure Server Callback /// </summary> /// <param name="mySecureTCPServer"></param> /// <param name="clientIndex"></param> void SecureConnectCallback(SecureTCPServer server, uint clientIndex) { try { Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "ConnectCallback: IPAddress: {0}. Index: {1}. Status: {2}", server.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex), clientIndex, server.GetServerSocketStatusForSpecificClient(clientIndex)); if (clientIndex != 0) { if (server.ClientConnected(clientIndex)) { if (!ConnectedClientsIndexes.Contains(clientIndex)) { ConnectedClientsIndexes.Add(clientIndex); } if (SharedKeyRequired) { if (!WaitingForSharedKey.Contains(clientIndex)) { WaitingForSharedKey.Add(clientIndex); } byte[] b = Encoding.GetEncoding(28591).GetBytes("SharedKey:"); server.SendDataAsync(clientIndex, b, b.Length, (x, y, z) => { }); Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Sent Shared Key Request to client at {0}", server.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex)); } else { OnServerClientReadyForCommunications(clientIndex); } if (HeartbeatRequired) { if (!HeartbeatTimerDictionary.ContainsKey(clientIndex)) { HeartbeatTimerDictionary.Add(clientIndex, new CTimer(HeartbeatTimer_CallbackFunction, clientIndex, HeartbeatRequiredIntervalMs)); } } server.ReceiveDataAsync(clientIndex, SecureReceivedDataAsyncCallback); } } else { Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Client attempt faulty."); if (!ServerStopped) { server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback); return; } } } catch (Exception ex) { Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error in Socket Status Connect Callback. Error: {0}", ex); } //Debug.Console(1, this, Debug.ErrorLogLevel, "((((((Server State bitfield={0}; maxclient={1}; ServerStopped={2}))))))", // server.State, // MaxClients, // ServerStopped); if ((server.State & ServerState.SERVER_LISTENING) != ServerState.SERVER_LISTENING && MaxClients > 1 && !ServerStopped) { Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Waiting for next connection"); server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback); } }