123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- using Newtonsoft.Json;
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Net.Http;
- using System.Net.NetworkInformation;
- using System.Net.Sockets;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Windows.Input;
- using Vinno.IUS.Common.Client.ViewModels;
- namespace SonopostSearchTool
- {
- public class MainViewModel : ViewModel
- {
- private CancellationTokenSource _tokenSource;
- private Socket _socket;
- private int _listenerPort = 9099;
- private bool _isBusy;
- private string _fixedIp;
- private string _url;
- private VBoxItem _selectedItem;
- private string _status;
- public bool IsBusy
- {
- get => _isBusy;
- set
- {
- if (_isBusy != value)
- {
- _isBusy = value;
- OnPropertyChanged(() => IsBusy);
- }
- }
- }
- public string FixedIP
- {
- get => _fixedIp;
- set
- {
- if(_fixedIp != value)
- {
- _fixedIp = value;
- OnPropertyChanged(()=> FixedIP);
- }
- }
- }
- public string Url
- {
- get => _url;
- set
- {
- if(_url != value)
- {
- _url = value;
- OnPropertyChanged(()=>Url);
- }
- }
- }
- public VBoxItem SelectedItem
- {
- get => _selectedItem;
- set
- {
- if(_selectedItem != value)
- {
- _selectedItem = value;
- Url = _selectedItem?.Url ?? "about:blank";
- if(_selectedItem != null && !string.IsNullOrEmpty(_selectedItem.IP))
- {
- Status = string.Format(TranslateHelper.Translate("Connected"), _selectedItem.DisplayName);
- }
- OnPropertyChanged(()=>SelectedItem);
- }
- }
- }
- public string Status
- {
- get => _status;
- set
- {
- if(_status != value)
- {
- _status = value;
- OnPropertyChanged(()=>Status);
- }
- }
- }
- public ICommand OpenCommand { get; set; }
- public ICommand RefreshCommand { get; set; }
-
- public ObservableCollection<VBoxItem> VBoxItems { get; set; }
- public MainViewModel()
- {
- VBoxItems = new ObservableCollection<VBoxItem>();
- OpenCommand = new ButtonCommand(OnOpenAsync);
- RefreshCommand = new ButtonCommand(OnRefresh);
- }
- private async void OnOpenAsync(object obj)
- {
- try
- {
- IsBusy = true;
- if (string.IsNullOrEmpty(FixedIP))
- {
- ShowMessage("AddressIsEmpty");
- return;
- }
- string reg = @"^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$";
- if (Regex.IsMatch(FixedIP, reg) == false)
- {
- ShowMessage("IPAddressIsWrong");
- return;
- }
- var result = await CheckIsExist(FixedIP);
- if (result == true)
- {
- Url = $"http://{FixedIP}:8080";
- }
- else
- {
- ShowMessage("DeviceIsWrong");
- }
- }
- catch (Exception e)
- {
- Logger.WriteLineError($"Open VBOX Error:{e}");
- }
- finally
- {
- IsBusy = false;
- }
-
- }
- private async Task<bool> CheckIsExist(string url)
- {
- try
- {
- var ip = url.Split(':')[0];
- var gateway = ip.Substring(0, ip.LastIndexOf('.')) + ".1";
- using (var httpClient = new HttpClient())
- {
- httpClient.Timeout = TimeSpan.FromSeconds(2);
- var result = await httpClient.PostAsync($"http://{url}/api/vbox?flag=ping&address={gateway}", null);
- if (result != null && result.StatusCode == HttpStatusCode.OK)
- {
- var jsonstr = await result.Content.ReadAsStringAsync();
- var msg = JsonConvert.DeserializeObject<PingMessage>(jsonstr);
- if (msg.Status == "200" && msg.Content.Contains("Success"))
- {
- return true;
- }
- }
- }
- }
- catch(TaskCanceledException)
- {
- //ignore
- }
- catch (Exception e)
- {
- Logger.WriteLineError($"Check VBox Exist Error:{e}");
- }
- return false;
-
- }
- private void OnRefresh(object obj)
- {
- try
- {
- Status = string.Empty;
- VBoxItems.Clear();
- Init();
- var localIps = GetAddressIP();
- StartSearch(localIps);
- }
- catch (Exception e)
- {
- Logger.WriteLineError($"Refresh Error:{e}");
- }
-
- }
- private IList<string> GetAddressIP()
- {
- IList<string> ips = new List<string>();
- foreach (IPAddress ipaddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
- {
- if (ipaddress.AddressFamily == AddressFamily.InterNetwork)
- {
- if(!string.IsNullOrEmpty(ipaddress.ToString()))
- {
- ips.Add(ipaddress.ToString());
- }
- }
- }
- return ips;
- }
- private void Init()
- {
- try
- {
- if(_socket != null)
- {
- return;
- }
- var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
- var ipEndPoints = ipProperties.GetActiveUdpListeners();
- // calculate port is in use or not
- while (ipEndPoints.Any(x => x.Port == _listenerPort))
- {
- _listenerPort++;
- }
- _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- uint IOC_IN = 0x80000000;
- uint IOC_VENDOR = 0x18000000;
- uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
- _socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
- //_socket.ReceiveTimeout = 3000;
- _socket.Bind(new IPEndPoint(IPAddress.Any, _listenerPort));
- StartReceiveThread();
- }
- catch (Exception e)
- {
- _listenerPort++;
- Logger.WriteLineError($"Start UDP Search Error:{e}");
- }
- }
- private void StartSearch(IList<string> localIps)
- {
- if (!localIps.Any())
- {
- return;
- }
- if (_tokenSource != null && !_tokenSource.IsCancellationRequested)
- {
- _tokenSource.Cancel();
- }
- _tokenSource = new CancellationTokenSource();
- Task.Run(async () => {
- try
- {
- MainDispatcher.Invoke(()=> IsBusy = true);
- foreach (var ip in localIps)
- {
- await SendMsgToServerAsync(ip);
- }
- }
- catch (TaskCanceledException)
- {
- //ignore
- }
- catch (Exception e)
- {
- Logger.WriteLineError($"StartSendPacages Error:{e}");
- }
- finally
- {
- MainDispatcher.Invoke(() =>
- {
- IsBusy = false;
- });
- }
- }, _tokenSource.Token);
- }
- private async Task SendMsgToServerAsync(string localIp)
- {
- var index = localIp.LastIndexOf('.');
- var tmp = localIp.Substring(0, index + 1);
- var localIndex = int.Parse(localIp.Substring(index + 1, localIp.Length - index - 1));
- for (int i = 0; i <= 255; i++)
- {
- if (_tokenSource.IsCancellationRequested)
- {
- return;
- }
- if (i == 1 || i == localIndex)
- {
- continue;
- }
- var ipaddress = IPAddress.Parse($"{tmp}{i}");
- var portData = BitConverter.GetBytes(_listenerPort);
- using (var ms = new MemoryStream())
- {
- ms.WriteByte(0x4C);
- ms.WriteByte(0x54);
- ms.Write(portData, 0, portData.Length);
- _socket.SendTo(ms.ToArray(), new IPEndPoint(ipaddress, 8888));
- }
- await Task.Delay(10, _tokenSource.Token);
- }
- }
- private void StopSearch()
- {
- _tokenSource?.Cancel();
- }
- private void StartReceiveThread()
- {
- Task.Run(() => {
- while (_socket != null)
- {
- try
- {
- var buffer = new byte[1024];
- EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); ;
- _socket.ReceiveFrom(buffer, ref remoteEndPoint);
- var bytesLen = new byte[4];
- Buffer.BlockCopy(buffer, 0, bytesLen, 0, 4);
- var bufferLen = BitConverter.ToInt32(bytesLen, 0);
- var contentBytes = new byte[bufferLen];
- Buffer.BlockCopy(buffer, 4, contentBytes, 0, bufferLen);
- var packageStr = Encoding.UTF8.GetString(contentBytes).TrimEnd();
- if (string.IsNullOrWhiteSpace(packageStr))
- continue;
- var package = JsonConvert.DeserializeObject<DevicePackage>(packageStr);
- if (package != null)
- {
- var vboxIp = package.NetworkInfo.FirstOrDefault()?.IP;
- var vboxItem = new VBoxItem(vboxIp,package.Port, package.Version);
- MainDispatcher.Invoke(new Action(()=> {
- if(VBoxItems.FirstOrDefault(c=>c.IP == vboxIp) == null)
- {
- VBoxItems.Add(vboxItem);
- }
- }));
- }
- }
- catch (TaskCanceledException)
- {
- //ignore
- }
- catch (Exception e)
- {
- Logger.WriteLineError($"Receive UDP Error:{e}");
- }
- }
- });
- }
- private void ShowMessage(string msg)
- {
- MainDispatcher.Invoke(() => {
- CustomMessageBox.Show(TranslateHelper.Translate(msg));
- });
- }
- protected override void DoDispose()
- {
- try
- {
- _tokenSource?.Cancel();
- if(_socket != null)
- {
- _socket.Close();
- _socket.Dispose();
- _socket = null;
- }
- base.DoDispose();
- }
- catch (Exception e)
- {
- Logger.WriteLineError($"DoDispose:{e}");
- }
-
- }
- private class PingMessage
- {
- public string Status { get; set; }
- public string Content { get; set; }
- }
- }
- }
|