private async Task ExecuteDiscoveryTask() { int repeatTime = EndpointController.REPEAT_DISCOVERY_TASK / 2; while (running) { Debug.WriteLine("#> [DiscoveryCloudletMulticast]: Started Cloudlet Discovery using Multicast UDP"); retry = 0; DatagramSocket socketSent = null; DatagramSocket socketReplay = null; try { socketSent = new DatagramSocket(); await socketSent.BindEndpointAsync(null, string.Empty); socketSent.JoinMulticastGroup(ip); socketReplay = new DatagramSocket(); socketReplay.MessageReceived += SocketOnMessageReceived; await socketReplay.BindServiceNameAsync(replyCloudletPort.ToString()); using (DataWriter writer = new DataWriter(await socketSent.GetOutputStreamAsync(ip, multicastPort.ToString()))) { while (retry < 60 && running) { writer.WriteString("mpos_cloudlet_req"); await writer.StoreAsync(); await writer.FlushAsync(); await Task.Delay(500); retry++; } } } catch (IOException e) { Debug.WriteLine("## [DiscoveryCloudletMulticast]: Any problem with i/o in multicast system!\n" + e.ToString()); } finally { socketSent.Dispose(); socketReplay.Dispose(); socketSent = null; socketReplay = null; } if (running) { Debug.WriteLine(">> [DiscoveryCloudletMulticast]: Retry Discovery Cloudlet, in " + repeatTime + " ms"); await Task.Delay(repeatTime); } else { Debug.WriteLine("#> [DiscoveryCloudletMulticast]: Finished Discovery Cloudlet"); } } }
private void CloseListenerSocket() { if (listenerSocket == null) { return; } listenerSocket.Dispose(); listenerSocket = null; }
private async Task DoWakeOnLan(string macAddress, string ipAddress, string port) { var socket = new DatagramSocket(); await socket.BindServiceNameAsync("0"); var o = await socket.GetOutputStreamAsync(new HostName(ipAddress), port); var writer = new DataWriter(o); writer.WriteBytes(GetBuffer(macAddress)); await writer.StoreAsync(); socket.Dispose(); }
async partial void SendTimeRequest() { var socket = new Windows.Networking.Sockets.DatagramSocket(); AsyncUdpResult asyncResult = null; try { var buffer = new byte[48]; buffer[0] = 0x1B; socket.MessageReceived += Socket_Completed_Receive; asyncResult = new AsyncUdpResult(socket); await socket.ConnectAsync(new Windows.Networking.HostName(_ServerAddress), "123").AsTask().ConfigureAwait(false); using (var udpWriter = new DataWriter(socket.OutputStream)) { udpWriter.WriteBytes(buffer); await udpWriter.StoreAsync().AsTask().ConfigureAwait(false); udpWriter.WriteBytes(buffer); await udpWriter.StoreAsync().AsTask().ConfigureAwait(false); asyncResult.Wait(OneSecond); } } catch (Exception ex) { try { if (socket != null) { ExecuteWithSuppressedExceptions(() => socket.MessageReceived -= this.Socket_Completed_Receive); ExecuteWithSuppressedExceptions(() => socket.Dispose()); } } finally { OnErrorOccurred(ExceptionToNtpNetworkException(ex)); } } finally { asyncResult?.Dispose(); } }
private void StartListener_Click(object sender, RoutedEventArgs e) { if (string.IsNullOrEmpty(ServiceName.Text)) { _rootPage.NotifyUser("Please provide a service name.", NotifyType.ErrorMessage); return; } if (listenerSocket != null) { _rootPage.NotifyUser("A listener socket is already set up.", NotifyType.ErrorMessage); return; } var isMulticastSocket = MulticastRadioButton.IsChecked == true; listenerSocket = new Windows.Networking.Sockets.DatagramSocket(); listenerSocket.MessageReceived += MessageReceived; if (isMulticastSocket) { listenerSocket.Control.MulticastOnly = true; } try { } catch (Exception exception) { listenerSocket.Dispose(); listenerSocket = null; if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) { throw; } _rootPage.NotifyUser("Start listening failed with error: " + exception.Message, NotifyType.ErrorMessage); } }
public static IObservable<ZeroconfRecord> Resolve(string protocol) { return Observable.Create<ZeroconfRecord>(async observer => { var socket = new DatagramSocket(); var s = Observable .FromEventPattern <TypedEventHandler<DatagramSocket, DatagramSocketMessageReceivedEventArgs>, DatagramSocketMessageReceivedEventArgs>( x => socket.MessageReceived += x, _ => socket.Dispose()) .Select(ProcessMessage) .Where(x => x != null) .Subscribe(observer); await socket.BindServiceNameAsync("5353"); socket.JoinMulticastGroup(new HostName("224.0.0.251")); var os = await socket.GetOutputStreamAsync(new HostName("224.0.0.251"), "5353"); var writer = new DataWriter(os); WriteQueryMessage(protocol, writer); writer.StoreAsync(); return s; }); }
/// <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> private async void StartListener_Click(object sender, RoutedEventArgs e) { if (String.IsNullOrEmpty(ServiceName.Text)) { rootPage.NotifyUser("Please provide a service name.", NotifyType.ErrorMessage); return; } if (listenerSocket != null) { rootPage.NotifyUser("A listener socket is already set up.", NotifyType.ErrorMessage); return; } bool isMulticastSocket = (MulticastRadioButton.IsChecked == true); listenerSocket = new DatagramSocket(); listenerSocket.MessageReceived += MessageReceived; if (isMulticastSocket) { // DatagramSockets conduct exclusive (SO_EXCLUSIVEADDRUSE) binds by default, effectively blocking // any other UDP socket on the system from binding to the same local port. This is done to prevent // other applications from eavesdropping or hijacking a DatagramSocket's unicast traffic. // // Setting the MulticastOnly control option to 'true' enables a DatagramSocket instance to share its // local port with any Win32 sockets that are bound using SO_REUSEADDR/SO_REUSE_MULTICASTPORT and // with any other DatagramSocket instances that have MulticastOnly set to true. However, note that any // attempt to use a multicast-only DatagramSocket instance to send or receive unicast data will result // in an exception being thrown. // // This control option is particularly useful when implementing a well-known multicast-based protocol, // such as mDNS and UPnP, since it enables a DatagramSocket instance to coexist with other applications // running on the system that also implement that protocol. listenerSocket.Control.MulticastOnly = true; } // Start listen operation. try { await listenerSocket.BindServiceNameAsync(ServiceName.Text); if (isMulticastSocket) { // Join the multicast group to start receiving datagrams being sent to that group. listenerSocket.JoinMulticastGroup(new HostName(RemoteAddress.Text)); rootPage.NotifyUser( "Listening on port " + listenerSocket.Information.LocalPort + " and joined to multicast group", NotifyType.StatusMessage); } else { rootPage.NotifyUser( "Listening on port " + listenerSocket.Information.LocalPort, NotifyType.StatusMessage); } // Enable scenario steps that require us to have an active listening socket. SendMessageButton.IsEnabled = true; CloseListenerButton.IsEnabled = true; } catch (Exception exception) { listenerSocket.Dispose(); listenerSocket = null; // 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; } rootPage.NotifyUser( "Start listening failed with error: " + exception.Message, NotifyType.ErrorMessage); } }
private async void SocketOnMessageReceived(DatagramSocket socket, DatagramSocketMessageReceivedEventArgs args) { using (var reader = new StreamReader(args.GetDataStream().AsStreamForRead(bufferSize))) { Debug.WriteLine("#> [DiscoveryCloudletMulticast]: Wait Reply..."); string message = await reader.ReadToEndAsync(); if (message.Contains("=")) { string[] extractMessage = message.Split(new char[] { '=' }); Stop(); MposFramework.Instance.EndpointController.FoundCloudlet(extractMessage[1]); Debug.WriteLine("#> [ReceiveReplyCloudlet]: Finished Reply Cloudlet listen"); } } socket.Dispose(); }
/// <summary> /// Searches for an available devices of specified type. /// </summary> /// <param name="searchTarget"> /// The type of the devices to search for. /// </param> /// <param name="timeForResponse"> /// The time (in seconds) of a search. /// </param> /// <returns> /// An observable collection which contains search results. /// </returns> public IObservable<SearchResponseMessage> Search(string searchTarget, int timeForResponse) { return Observable.Create<SearchResponseMessage>(async observer => { var searchSocket = new DatagramSocket(); // Handling responses from found devices searchSocket.MessageReceived += async (sender, args) => { var dataReader = args.GetDataReader(); dataReader.InputStreamOptions = InputStreamOptions.Partial; if (dataReader.UnconsumedBufferLength == 0) { await dataReader.LoadAsync(1024); } var message = dataReader.ReadString(dataReader.UnconsumedBufferLength); try { var response = SearchResponseMessage.Create(message); observer.OnNext(response); } catch (ArgumentException ex) { logger.Instance().Warning(ex, "The received M-Search response has been ignored.", "Message".As(message)); } }; await searchSocket.BindServiceNameAsync("0"); searchSocket.JoinMulticastGroup(this.multicastHost); var request = MSearchRequestFormattedString.F(searchTarget, timeForResponse); var buffer = Encoding.UTF8.GetBytes(request).AsBuffer(); // Sending the search request to a multicast group var outputStream = await searchSocket.GetOutputStreamAsync(this.multicastHost, MulticastPort.ToString()); await outputStream.WriteAsync(buffer); await outputStream.WriteAsync(buffer); // Stop listening for a devices when timeout for responses is expired Observable.Timer(TimeSpan.FromSeconds(timeForResponse)).Subscribe(s => { observer.OnCompleted(); searchSocket.Dispose(); }); logger.Instance().Debug("M-Search request has been sent. [multicastHost={0}, searchTarget={1}]".F(multicastHost.DisplayName, searchTarget)); return searchSocket.Dispose; }); }
public async Task SendMessage(byte[] message, string host, string port) { sender = new DatagramSocket(); try { using (var stream = await sender.GetOutputStreamAsync(new HostName(host), port)) { var writer = new DataWriter(stream); writer.WriteBytes(message); await writer.StoreAsync(); playPage.DisplayMessages(name + " :Send message"); } } catch (Exception ex) { playPage.DisplayMessages(name + " :Error: Send Message\n" + ex.ToString()); } sender.Dispose(); }
/// <summary> /// Search devices and retrieve their device info. /// </summary> /// <param name="timeoutSec">Seconds to wait before invokation of OnTimeout.</param> /// <param name="OnServerFound">Success callback. This will be invoked for each devices until OnTimeout is invoked.</param> /// <param name="OnTimeout">Timeout callback.</param> public async void SearchDevices(int timeoutSec, Action<DeviceInfo> OnServerFound, Action OnTimeout) { if (OnServerFound == null || OnTimeout == null) { throw new ArgumentNullException(); } Debug.WriteLine("DeviceFinder.SearchDevices"); if (timeoutSec < 2) { timeoutSec = 2; } const int MX = 1; var ssdp_data = new StringBuilder() .Append("M-SEARCH * HTTP/1.1").Append("\r\n") .Append("HOST: ").Append(multicast_address).Append(":").Append(ssdp_port.ToString()).Append("\r\n") .Append("MAN: ").Append("\"ssdp:discover\"").Append("\r\n") .Append("MX: ").Append(MX.ToString()).Append("\r\n") .Append("ST: urn:schemas-sony-com:service:ScalarWebAPI:1").Append("\r\n") //.Append("ST: ssdp:all").Append("\r\n") // For debug .Append("\r\n") .ToString(); byte[] data_byte = Encoding.UTF8.GetBytes(ssdp_data); //Debug.WriteLine(ssdp_data); bool timeout_called = false; var DD_Handler = new AsyncCallback(ar => { if (timeout_called) { return; } var req = ar.AsyncState as HttpWebRequest; try { var res = req.EndGetResponse(ar) as HttpWebResponse; using (var reader = new StreamReader(res.GetResponseStream(), Encoding.UTF8)) { try { var info = AnalyzeDD(reader.ReadToEnd()); NotifyFoundAsync(info, OnServerFound); } catch (Exception) { //Invalid XML. } } } catch (WebException) { //Invalid DD location or network error. } }); #if WINDOWS_PHONE Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); socket.SendBufferSize = data_byte.Length; SocketAsyncEventArgs snd_event_args = new SocketAsyncEventArgs(); snd_event_args.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(multicast_address), ssdp_port); snd_event_args.SetBuffer(data_byte, 0, data_byte.Length); SocketAsyncEventArgs rcv_event_args = new SocketAsyncEventArgs(); rcv_event_args.SetBuffer(new byte[result_buffer], 0, result_buffer); var SND_Handler = new EventHandler<SocketAsyncEventArgs>((sender, e) => { if (e.SocketError == SocketError.Success && e.LastOperation == SocketAsyncOperation.SendTo) { socket.ReceiveBufferSize = result_buffer; socket.ReceiveAsync(rcv_event_args); } }); snd_event_args.Completed += SND_Handler; var RCV_Handler = new EventHandler<SocketAsyncEventArgs>((sender, e) => { if (e.SocketError == SocketError.Success && e.LastOperation == SocketAsyncOperation.Receive) { string result = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred); //Debug.WriteLine(result); GetDDAsync(DD_Handler, result); socket.ReceiveAsync(e); } }); rcv_event_args.Completed += RCV_Handler; socket.SendToAsync(snd_event_args); #elif NETFX_CORE var sock = new DatagramSocket(); sock.MessageReceived += (sender, args) => { if (timeout_called || args == null) { return; } var reader = args.GetDataReader(); string data = reader.ReadString(reader.UnconsumedBufferLength); Debug.WriteLine(data); GetDDAsync(DD_Handler, data); }; try { await sock.BindServiceNameAsync(ssdp_port.ToString()); } catch (Exception) { Debug.WriteLine("Duplicate search is not supported"); return; } var host = new HostName(multicast_address); sock.JoinMulticastGroup(host); try { var output = await sock.GetOutputStreamAsync(host, ssdp_port.ToString()); await output.WriteAsync(data_byte.AsBuffer()); await sock.OutputStream.FlushAsync(); } catch (Exception) { Debug.WriteLine("Failed to send multicast"); return; } #endif await RunTimeoutInvokerAsync(timeoutSec, () => { Debug.WriteLine("SSDP Timeout"); timeout_called = true; #if WINDOWS_PHONE snd_event_args.Completed -= SND_Handler; rcv_event_args.Completed -= RCV_Handler; socket.Close(); #elif NETFX_CORE sock.Dispose(); #endif OnTimeout.Invoke(); }); }