123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- using Edge.Core.Parser.BinaryParser.Util;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Logging.Abstractions;
- using PetroChinaOnlineWatchPlugin.MessageEntity.Outgoing;
- using System;
- using System.Diagnostics;
- using System.Net;
- using System.Net.Sockets;
- namespace PetroChinaOnlineWatchPlugin
- {
- internal class HeartBeatUdpProxy
- {
- public event EventHandler OnDataReceived;
- public static HeartBeatUdpProxy Default => instance;
- private static readonly HeartBeatUdpProxy instance = new HeartBeatUdpProxy();
- private int heartBeatUdpPortNumber = 0;
- private UdpClient heartBeatUdpClient;
- private ILogger logger = NullLogger.Instance;
- private string localIpAddresses = string.Empty;
- private string broadcastIpAddresses = string.Empty;
- private AppConfigV1 appConfig;
- public bool Start(AppConfigV1 appConfig, ILogger logger)
- {
- this.appConfig = appConfig;
- this.logger = logger;
- heartBeatUdpPortNumber = appConfig.HeartBeatPortNumber;
- // setup heartBeat UdpClient
- heartBeatUdpClient = new UdpClient(new IPEndPoint(IPAddress.Any, heartBeatUdpPortNumber))
- { EnableBroadcast = true };
- heartBeatUdpClient.BeginReceive(Udp_DataReceived, null);
- GetLocalIp();
- return true;
- }
- public void Udp_SendData()
- {
- try
- {
- var outHeartBeat = new HeartBeatOut()
- {
- IpAddress = localIpAddresses,
- Port = ConnectionController.Default.TcpListenPort,
- Subnet = appConfig.LocalSubnet,
- Node = appConfig.LocalNode
- };
- byte[] heartBeatRawDataToSend = Parser.Default.Serialize(outHeartBeat);
- logger.LogTrace($"Udp Outgoing--->: 0x{heartBeatRawDataToSend.ToHexLogString()}");
- heartBeatUdpClient.Send(heartBeatRawDataToSend, heartBeatRawDataToSend.Length,
- broadcastIpAddresses, heartBeatUdpPortNumber);
- }
- catch (Exception ex)
- {
- logger.LogError($"Exception in Udp_SendData(...):\r\n{ex}");
- }
- }
- private void Udp_DataReceived(IAsyncResult ar)
- {
- try
- {
- // IFSF always have 10 bytes heartbeat: ip0.ip1.ip2,ip3,port(2 bytes),4 ifsf standard bytes
- var broadcastHeartBeatReceiveEP = new IPEndPoint(IPAddress.Any, 0);
- byte[] heartBeatBytes = heartBeatUdpClient.EndReceive(ar, ref broadcastHeartBeatReceiveEP);
- logger.LogTrace($"Udp Incoming--->: 0x{heartBeatBytes.ToHexLogString()}");
- dynamic heartBeat = Parser.Default.Deserialize(heartBeatBytes);
- logger.LogTrace($"HeartBeatIncoming--->: {heartBeat.ToString()}");
- if (heartBeat.Subnet == appConfig.RemoteSubnet && heartBeat.Node == appConfig.RemoteNode)
- {
- logger.LogTrace($"Received heart beat from IpAddress:Port, {heartBeat.ToString()}");
- if (!ConnectionController.Default.TcpClientInstance.Connected)
- OnDataReceived?.Invoke(this, new UdpDataEventArgs() { IpAddress = heartBeat.IpAddress, Port = heartBeat.Port });
- }
- }
- catch (Exception ex)
- {
- logger.LogError($"Exception in Udp_DataReceived(...):\r\n{ex}");
- }
- finally
- {
- heartBeatUdpClient.BeginReceive(Udp_DataReceived, null);
- }
- }
- private void GetLocalIp()
- {
- try
- {
- //var localIpAddresses = NetworkInterface.GetAllNetworkInterfaces()
- // .Where(i => i.SupportsMulticast && i.Supports(NetworkInterfaceComponent.IPv4))
- // .SelectMany(i => i.GetIPProperties().UnicastAddresses)
- // .Select(ad => ad.Address)
- // .Where(ad => ad.AddressFamily == AddressFamily.InterNetwork);
- //logger.LogInformation("Local ip addresses are: " + localIpAddresses.Select(i => i.ToString())
- // .Aggregate((acc, n) => acc + ", " + n));
- var cmd = new Process();
- cmd.StartInfo.FileName = "ipconfig.exe";
- cmd.StartInfo.RedirectStandardOutput = true;
- cmd.StartInfo.RedirectStandardInput = true;
- cmd.StartInfo.UseShellExecute = false;
- cmd.StartInfo.CreateNoWindow = true;
- cmd.Start();
- string info = cmd.StandardOutput.ReadToEnd();
- cmd.WaitForExit();
- cmd.Close();
- info = info.Substring(info.IndexOf(appConfig.NetworkConnections));
- string ipFlag = "IPv4 Address. . . . . . . . . . . : ";
- int index = info.IndexOf(ipFlag);
- if (index > 0)
- {
- info = info?.Substring(index + ipFlag.Length);
- }
- else
- {
- ipFlag = "IPv4 地址 . . . . . . . . . . . . : ";
- info = info?.Substring(info.IndexOf(ipFlag) + ipFlag.Length);
- }
- localIpAddresses = info?.Split("\r\n")[0];
- logger.LogInformation($"Local ip addresses is: {localIpAddresses}");
- ipFlag = "Subnet Mask . . . . . . . . . . . : ";
- index = info.IndexOf(ipFlag);
- if (index > 0)
- {
- info = info?.Substring(index + ipFlag.Length);
- }
- else
- {
- ipFlag = "子网掩码 . . . . . . . . . . . . : ";
- info = info?.Substring(info.IndexOf(ipFlag) + ipFlag.Length);
- }
- string subnetMask = info?.Split("\r\n")[0];
- logger.LogInformation($"Local subnet mask is: {subnetMask}");
- broadcastIpAddresses = GetBroadcastIpAddresses(localIpAddresses, subnetMask);
- logger.LogInformation($"Broadcast ip addresses is: {broadcastIpAddresses}");
- }
- catch (Exception ex)
- {
- logger.LogError($"Exception in GetLocalIp(...):\r\n{ex}");
- }
- }
- private string GetBroadcastIpAddresses(string ipAddress, string subnetMask)
- {
- byte[] ipBuffer = IpAddress2Bytes(ipAddress);
- byte[] smBuffer = IpAddress2Bytes(subnetMask);
- return $"{ipBuffer[0] | Negate(smBuffer[0])}.{ipBuffer[1] | Negate(smBuffer[1])}." +
- $"{ipBuffer[2] | Negate(smBuffer[2])}.{ipBuffer[3] | Negate(smBuffer[3])}";
- }
- private byte Negate(byte value)
- {
- int first = value >> 7;
- if (first == 1)
- {
- value = (byte)(value & 0x7F);
- value = (byte)(~value & 0x7F);
- }
- else
- {
- value = (byte)(~value);
- }
- return value;
- }
- private byte[] IpAddress2Bytes(string ipAddress)
- {
- byte[] buffer = new byte[4];
- int i = 0;
- foreach (string item in ipAddress.Split('.'))
- {
- buffer[i++] = byte.Parse(item);
- }
- return buffer;
- }
- }
- public class UdpDataEventArgs : EventArgs
- {
- public string IpAddress { get; set; }
- public int Port { get; set; }
- }
- }
|