//Call this to create a new instance of this listener class, rather than the constructor public static SocketListenerSvr CreateNew(string remoteSocketListenerSvrName, string port, bool bindtoany, string passkey) { SocketListenerSvr _SocketListenerSvr = null; if (Sox.AppMode == AppMode.None) { if (Sox.IsNumeric_uint(port)) { _SocketListenerSvr = new SocketListenerSvr(remoteSocketListenerSvrName, port, bindtoany, passkey); if (_SocketListenerSvr != null) { Sox.AppMode = AppMode.NewListner; } } else { Sox.Instance.Log( "Invalid Port string for listener service.", NotifyType.ErrorMessage); } } else { Sox.Instance.Log( "Unable to create SocketListner. Incorrect AppMode.", NotifyType.ErrorMessage); } return(_SocketListenerSvr); }
public static void CloseSockets() { if (Sox.AppMode == AppMode.None) { Sox.Instance.Log( "No instantiated socket to close.", NotifyType.WarningMessage); } else { Sox.CancelActions(); //SocketClientServer.WaitForToken(); object outValue; if (CoreApplication.Properties.TryGetValue("clientDataWriter", out outValue)) { // Remove the data writer from the list of application properties as we are about to close it. CoreApplication.Properties.Remove("clientDataWriter"); DataWriter dataWriter = (DataWriter)outValue; // To reuse the socket with another data writer, the application must detach the stream from the // current writer before disposing it. This is added for completeness, as this sample closes the socket // in the very next block. dataWriter.DetachStream(); dataWriter.Dispose(); } if (CoreApplication.Properties.TryGetValue("clientSocket", out outValue)) { // Remove the socket from the list of application properties as we are about to close it. CoreApplication.Properties.Remove("clientSocket"); StreamSocket socket = (StreamSocket)outValue; // StreamSocket.Close() is exposed through the Dispose() method in C#. // The call below explicitly closes the socket. socket.Dispose(); } if (CoreApplication.Properties.TryGetValue("listener", out outValue)) { // Remove the listener from the list of application properties as we are about to close it. CoreApplication.Properties.Remove("listener"); StreamSocketListener listener = (StreamSocketListener)outValue; // StreamSocketListener.Close() is exposed through the Dispose() method in C#. // The call below explicitly closes the socket. listener.Dispose(); } CoreApplication.Properties.Remove("connected"); CoreApplication.Properties.Remove("adapter"); CoreApplication.Properties.Remove("serverAddress"); Sox.Instance.Log("Socket and listener closed", NotifyType.StatusMessage); Sox.AppMode = AppMode.None; } Sox.AppMode = AppMode.None; }
private async Task NotifyUserFromAsyncThread(string strMessage, NotifyType type) { Sox.StartToken(); await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { Sox.Instance.Log(strMessage, type); }).AsTask(Sox.CancelToken); }
public SocketClient(string remoteSocketListenerSvrName, string port, bool bindtoany) { if (Sox.IsNumeric_uint(port)) { RemoteSocketListenerSvrName = remoteSocketListenerSvrName; PortOrServicenameForListener = port; } else { Sox.Instance.Log( "Invalid Port string for client.", NotifyType.ErrorMessage); } }
//We only use this constructor: public SocketListenerSvr(string remoteSocketListenerSvrName, string port, bool bindtoany, string passkey) { Passkey = passkey; if (Sox.IsNumeric_uint(port)) { BindToAny_IsChecked = bindtoany; RemoteSocketListenerSvrName = remoteSocketListenerSvrName; PortOrServicenameForListener = port; //Hook up a local ListenerConnection Event handler this.ListenerConnection += SocketListenerSvr_ListenerConnection; } else { Sox.Instance.Log( "Invalid Port string for listener service.", NotifyType.ErrorMessage); } }
/// <summary> /// Invoked once a connection is accepted by StreamSocketListener. /// </summary> /// <param name="sender">The listener that accepted the connection.</param> /// <param name="args">Parameters associated with the accepted connection.</param> private async void OnConnection( StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) { DataReader reader = new DataReader(args.Socket.InputStream); try { //Windows.Storage.Streams.Buffer Out = new Windows.Storage.Streams.Buffer(100); //await args.Socket.OutputStream.WriteAsync(Out); while (true) { // Read first 4 bytes (length of the subsequent string). Sox.StartToken(); uint sizeFieldCount = await reader.LoadAsync(sizeof(uint)).AsTask(Sox.CancelToken); if (sizeFieldCount != sizeof(uint)) { // The underlying socket was closed before we were able to read the whole data. return; } // Read the string. uint stringLength = reader.ReadUInt32(); Sox.StartToken(); uint actualStringLength = await reader.LoadAsync(stringLength).AsTask(Sox.CancelToken); if (stringLength != actualStringLength) { // The underlying socket was closed before we were able to read the whole data. return; } string data = reader.ReadString(actualStringLength); await NotifyUserFromAsyncThread( String.Format("Received data: \"{0}\"", data), NotifyType.StatusMessage); //data should be the string Passkey + comamnd char + Parameter string (can be "") //If of that format that get the command and parameter and fire the ListenerConnection Event if (data.Length > 0) { if (data.Length >= Passkey.Length) { if (Passkey == data.Substring(0, Passkey.Length)) { char command = data[Passkey.Length]; string param = ""; if (data.Length > Passkey.Length + 1) { param = data.Substring(Passkey.Length + 1); } string msg = string.Format("(InConnection) Command: '{0}' Param= \"{1}\" recvd", command, param); Sox.Instance.Log(msg, NotifyType.StatusMessage); //Fire the ListenerConnection Event await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { ListenerConnection.Invoke(command, param); }).AsTask(Sox.CancelToken); } else { Sox.Instance.Log("Null Command recvd.", NotifyType.StatusMessage); } } else { Sox.Instance.Log("Null Message recvd.", NotifyType.ErrorMessage); } } else { Sox.Instance.Log("Null data recvd.", NotifyType.ErrorMessage); } } } catch (TaskCanceledException) { Sox.Instance.Log("Cancelled.", NotifyType.StatusMessage); } catch (Exception exception) { // If this is an unknown status it means that the error is fatal and retry will likely fail. if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) { throw; } await NotifyUserFromAsyncThread( "Read stream failed with error: " + exception.Message, NotifyType.ErrorMessage); } }
/// <summary> /// This is the click handler for the 'StartListener' button. /// </summary> /// <param name="sender">Object for which the event was generated.</param> /// <param name="e">Event's parameters.</param> public async void StartListener() { if (Sox.AppMode != AppMode.NewListner) { if (Sox.AppMode == AppMode.ListenerStarted) { Sox.Instance.Log( "Start listening failed with warning: App Listener Socket already started", NotifyType.WarningMessage); } else { Sox.Instance.Log( "Start listening failed with error: App not in Listner Mode", NotifyType.ErrorMessage); } } else { // Overriding the listener here is safe as it will be deleted once all references to it are gone. // However, in many cases this is a dangerous pattern to override data semi-randomly (each time user // clicked the button) so we block it here. if (CoreApplication.Properties.ContainsKey("listener")) { Sox.Instance.Log( "This step has already been executed.", NotifyType.ErrorMessage); return; } if (String.IsNullOrEmpty(PortOrServicenameForListener)) { Sox.Instance.Log("Please provide a service name.", NotifyType.ErrorMessage); return; } CoreApplication.Properties.Remove("serverAddress"); LocalHostItem selectedLocalHost = null; if ((BindToAddress_IsChecked == true) || (BindToAdapter_IsChecked == true)) { selectedLocalHost = new LocalHostItem(RemoteSocketListenerSvrName); if (selectedLocalHost == null) { Sox.Instance.Log("Please select an address / adapter.", NotifyType.ErrorMessage); return; } // The user selected an address. For demo purposes, we ensure that connect will be using the same // address. CoreApplication.Properties.Add("serverAddress", selectedLocalHost.LocalHost.CanonicalName); } StreamSocketListener listener = new StreamSocketListener(); listener.ConnectionReceived += OnConnection; // If necessary, tweak the listener's control options before carrying out the bind operation. // These options will be automatically applied to the connected StreamSockets resulting from // incoming connections (i.e., those passed as arguments to the ConnectionReceived event handler). // Refer to the StreamSocketListenerControl class' MSDN documentation for the full list of control options. listener.Control.KeepAlive = false; // Start listen operation. try { if (BindToAny_IsChecked == true) { // Don't limit traffic to an address or an adapter. Sox.StartToken(); await listener.BindServiceNameAsync(PortOrServicenameForListener).AsTask(Sox.CancelToken); Sox.Instance.Log("Listening", NotifyType.StatusMessage); } else if (BindToAddress_IsChecked == true) { // Try to bind to a specific address. Sox.StartToken(); await listener.BindEndpointAsync(selectedLocalHost.LocalHost, PortOrServicenameForListener).AsTask(Sox.CancelToken); Sox.Instance.Log( "Listening on address " + selectedLocalHost.LocalHost.CanonicalName, NotifyType.StatusMessage); Sox.Instance.Log( "On Port " + PortOrServicenameForListener, NotifyType.StatusMessage); } else if (BindToAdapter_IsChecked == true) { // Try to limit traffic to the selected adapter. // This option will be overridden by interfaces with weak-host or forwarding modes enabled. NetworkAdapter selectedAdapter = selectedLocalHost.LocalHost.IPInformation.NetworkAdapter; // For demo purposes, ensure that we use the same adapter in the client connect scenario. CoreApplication.Properties.Add("adapter", selectedAdapter); Sox.StartToken(); await listener.BindServiceNameAsync( PortOrServicenameForListener, SocketProtectionLevel.PlainSocket, selectedAdapter).AsTask(Sox.CancelToken); Sox.Instance.Log( "Listening on adapter " + selectedAdapter.NetworkAdapterId, NotifyType.StatusMessage); } // Save the socket, so subsequent steps can use it. CoreApplication.Properties.Add("listener", listener); Sox.AppMode = AppMode.ListenerStarted; } catch (TaskCanceledException) { Sox.Instance.Log("Cancelled.", NotifyType.StatusMessage); Sox.AppMode = AppMode.NewListner; if (CoreApplication.Properties.ContainsKey("listener")) { // Remove the listener from the list of application properties as it wasn't connected. CoreApplication.Properties.Remove("listener"); } } catch (Exception exception) { if (CoreApplication.Properties.ContainsKey("listener")) { // Remove the listener from the list of application properties as it wasn't connected. CoreApplication.Properties.Remove("listener"); } Sox.AppMode = AppMode.NewListner; // If this is an unknown status it means that the error is fatal and retry will likely fail. if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) { throw; } Sox.Instance.Log( "Start listening failed with error: " + exception.Message, NotifyType.ErrorMessage); } } }
/// <summary> /// This is the click handler for the 'SendHello' button. /// </summary> /// <param name="sender">Object for which the event was generated.</param> /// <param name="e">Event's parameters.</param> public async Task <bool> Send(string SendData) { if (Sox.AppMode != AppMode.ClientSocketReadyToSend) { if (Sox.AppMode == AppMode.ClientSocketConnected) { Sox.Instance.Log( "Client send failed with warning: App Client Socket connected but not ready to send.", NotifyType.ErrorMessage); } else { Sox.Instance.Log( "Client send failed with error: App not in new Client Ready To Send Mode", NotifyType.ErrorMessage); } return(false); } string stringToSend = SendData;// "Hello"; if (!CoreApplication.Properties.ContainsKey("connected")) { Sox.Instance.Log("Client not connected.", NotifyType.ErrorMessage); return(false); } else { object outValue; StreamSocket socket; if (!CoreApplication.Properties.TryGetValue("clientSocket", out outValue)) { Sox.Instance.Log("Client socket not enabled.", NotifyType.ErrorMessage); return(false); } else { socket = (StreamSocket)outValue; // Create a DataWriter if we did not create one yet. Otherwise use one that is already cached. DataWriter writer; if (!CoreApplication.Properties.TryGetValue("clientDataWriter", out outValue)) { writer = new DataWriter(socket.OutputStream); CoreApplication.Properties.Add("clientDataWriter", writer); } else { writer = (DataWriter)outValue; } // Write first the length of the string as UINT32 value followed up by the string. // Writing data to the writer will just store data in memory. string actualStringToSend = Passkey + stringToSend; writer.WriteUInt32(writer.MeasureString(actualStringToSend)); writer.WriteString(actualStringToSend); // Write the locally buffered data to the network. try { Sox.StartToken(); await writer.StoreAsync().AsTask(Sox.CancelToken); SendOutput = "\"" + stringToSend + "\" sent successfully."; } catch (TaskCanceledException) { Sox.Instance.Log("Canceled.", NotifyType.StatusMessage); return(false); } catch (Exception exception) { // If this is an unknown status it means that the error if fatal and retry will likely fail. if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) { throw; } Sox.Instance.Log("Send failed with error: " + exception.Message, NotifyType.ErrorMessage); return(false); } } } return(true); }
/// <summary> /// This is the click handler for the 'ConnectSocket' button. /// </summary> /// <param name="sender">Object for which the event was generated.</param> /// <param name="e">Event's parameters.</param> public async Task ConnectSocket() { if (Sox.AppMode != AppMode.NewClient) { if (Sox.AppMode == AppMode.ClientSocketConnected) { Sox.Instance.Log( "Start client failed with warning: App Client Socket already connected", NotifyType.WarningMessage); } else { Sox.Instance.Log( "Start client failed with error: App not in new Client Mode", NotifyType.ErrorMessage); } } else { HostName hostName = null; if (CoreApplication.Properties.ContainsKey("clientSocket")) { Sox.Instance.Log( "This step has already been executed.", NotifyType.ErrorMessage); //return; } else { if (string.IsNullOrEmpty(PortOrServicenameForListener)) //(String.IsNullOrEmpty(ServiceNameForConnect)) { Sox.Instance.Log("Please provide a service name.", NotifyType.ErrorMessage); //return; } else { bool returnNow = false; if (string.IsNullOrEmpty(RemoteSocketListenerSvrName)) //(String.IsNullOrEmpty(ServiceNameForConnect)) { Sox.Instance.Log("Please provide a server name.", NotifyType.ErrorMessage); //return; returnNow = true; } // By default 'HostNameForConnect' is disabled and host name validation is not required. When enabling the // text box validating the host name is required since it was received from an untrusted source // (user input). The host name is validated by catching ArgumentExceptions thrown by the HostName // constructor for invalid input. else { try { hostName = new HostName(RemoteSocketListenerSvrName);// HostNameForConnect.Text); } catch (TaskCanceledException) { Sox.Instance.Log("Canceled.", NotifyType.StatusMessage); } catch (ArgumentException) { Sox.Instance.Log("Error: Invalid host name.", NotifyType.ErrorMessage); //return; returnNow = true; } } if (!returnNow) { StreamSocket socket = new StreamSocket(); // If necessary, tweak the socket's control options before carrying out the connect operation. // Refer to the StreamSocketControl class' MSDN documentation for the full list of control options. socket.Control.KeepAlive = false; try { if (adapter == null) { Sox.Instance.Log("Connecting to: " + hostName.DisplayName, NotifyType.StatusMessage); Sox.Instance.Log("On Port: " + PortOrServicenameForListener, NotifyType.StatusMessage); Sox.StartToken(); // Connect to the server (by default, the listener we created in the previous step). await socket.ConnectAsync(hostName, PortOrServicenameForListener).AsTask(Sox.CancelToken); Sox.Instance.Log("Connected", NotifyType.StatusMessage); CoreApplication.Properties.Add("clientSocket", socket); } else { Sox.Instance.Log( "Connecting to: " + RemoteSocketListenerSvrName + " using network adapter " + adapter.NetworkAdapterId, NotifyType.StatusMessage); // Connect to the server (by default, the listener we created in the previous step) // limiting traffic to the same adapter that the user specified in the previous step. // This option will be overridden by interfaces with weak-host or forwarding modes enabled. Sox.StartToken(); await socket.ConnectAsync( hostName, PortOrServicenameForListener,// ServiceNameForConnect.Text, SocketProtectionLevel.PlainSocket, adapter).AsTask(Sox.CancelToken); // Save the socket, so subsequent steps can use it. Sox.Instance.Log( "Connected using network adapter " + adapter.NetworkAdapterId, NotifyType.StatusMessage); } // Mark the socket as connected. Set the value to null, as we care only about the fact that the // property is set. CoreApplication.Properties.Add("connected", null); } catch (TaskCanceledException) { if (CoreApplication.Properties.ContainsKey("connected")) { CoreApplication.Properties.Remove("connected"); } Sox.AppMode = AppMode.NewClient; Sox.Instance.Log("Cancelled.", NotifyType.StatusMessage); } catch (Exception exception) { if (CoreApplication.Properties.ContainsKey("connected")) { CoreApplication.Properties.Remove("connected"); } Sox.AppMode = AppMode.NewClient; // If this is an unknown status it means that the error is fatal and retry will likely fail. if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) { throw; } Sox.Instance.Log("Connect failed with error: " + exception.Message, NotifyType.ErrorMessage); } } } } } }
public Sox() { Instance = this; IsPairing = false; }
public static void Start() { var log = new Sox(); AppMode = AppMode.None; }