Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Net.NetworkInformation;
- using System.Net.Sockets;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Windows;
- namespace ClusterXWorker
- {
- public class Peer
- {
- public IPEndPoint EndPoint { get; set; }
- public string ComputerName { get; set; }
- public DateTime LastAlive { get; set; }
- public bool RunningProcess { get; set; }
- }
- public class Message
- {
- public IPEndPoint EndPoint { get; set; }
- public byte[] Data { get; set; }
- }
- public class Cluster
- {
- public int Port { get; set; } = 21370;
- public int Timeout { get; set; } = 10000;
- private UdpClient _client;
- private Task _listenerTask;
- private Task _senderTask;
- private Task _discoverTask;
- private Queue<Message> _sendQueue = new Queue<Message>();
- private List<Peer> _peers = new List<Peer>();
- private IPEndPoint _serverEndPoint = null;
- private Process _runningProcess = null;
- public bool Discover { get; set; } = false;
- public bool IsServer { get; set; } = false;
- public void Start()
- {
- _client = new UdpClient(Port);
- _client.EnableBroadcast = true;
- Log($"Listening on port {Port}");
- _listenerTask = Task.Run(ListenerThreadFunc);
- _senderTask = Task.Run(SenderThreadFunc);
- if (Discover)
- _discoverTask = Task.Run(DiscoverThreadFunc);
- }
- public EventHandler<Peer> PeerConnected;
- public EventHandler<Peer> PeerDisconnected;
- public EventHandler<Peer> PeerStatus;
- private async Task ListenerThreadFunc()
- {
- while (true)
- {
- try
- {
- var result = await _client.ReceiveAsync();
- byte id = result.Buffer[0];
- // Discover request
- if (id == 0xC0)
- {
- //Log($"Received discover from {result.RemoteEndPoint}");
- SendComputerInfo(result.RemoteEndPoint);
- }
- // Computer info
- else if (id == 0xC1)
- {
- using (var s = new MemoryStream(result.Buffer))
- {
- var b = new BinaryReader(s);
- b.ReadByte(); // Packet id
- var computerName = b.ReadString();
- var runningProcess = b.ReadBoolean();
- lock (_peers)
- {
- var peer = _peers.FirstOrDefault(p =>
- p.EndPoint.Address == result.RemoteEndPoint.Address ||
- p.ComputerName == computerName);
- if (peer == null)
- {
- peer = new Peer()
- {
- EndPoint = result.RemoteEndPoint,
- ComputerName = computerName,
- LastAlive = DateTime.Now,
- };
- _peers.Add(peer);
- PeerConnected?.Invoke(this, peer);
- Log($"{computerName} connected from {peer.EndPoint}");
- }
- else
- {
- peer.ComputerName = computerName;
- peer.LastAlive = DateTime.Now;
- peer.RunningProcess = runningProcess;
- PeerStatus?.Invoke(this, peer);
- }
- }
- }
- }
- // Message
- else if (id == 0xC2)
- {
- using (var s = new MemoryStream(result.Buffer))
- {
- var b = new BinaryReader(s);
- b.ReadByte(); // Packet id
- var message = b.ReadString();
- Log($"Message from {result.RemoteEndPoint}: {message}");
- }
- }
- // Run process
- else if (id == 0xC3 && !IsServer)
- {
- if (_runningProcess != null)
- {
- _runningProcess.Refresh();
- if (!_runningProcess.HasExited)
- continue;
- }
- using (var s = new MemoryStream(result.Buffer))
- {
- var b = new BinaryReader(s);
- b.ReadByte(); // Packet id
- var filename = b.ReadString();
- var arguments = b.ReadString();
- Log($"{result.RemoteEndPoint} requests process start: {filename} {arguments}");
- _serverEndPoint = result.RemoteEndPoint;
- try
- {
- _runningProcess = Process.Start(filename,
- arguments.Replace("{IP}", _serverEndPoint.Address.ToString()));
- Thread.Sleep(300);
- _runningProcess.Refresh();
- if (_runningProcess.HasExited)
- {
- SendErrorMessage(_serverEndPoint,
- $"Process creation failed with exit code: {_runningProcess.ExitCode}");
- Log($"Process creation failed with exit code: {_runningProcess.ExitCode}");
- }
- }
- catch (Exception e)
- {
- Log($"{e}");
- SendErrorMessage(_serverEndPoint, $"Process creation failed: {e}");
- }
- }
- }
- // Stop process
- else if (id == 0xC4)
- {
- if (_runningProcess != null)
- {
- _runningProcess.Refresh();
- if (_runningProcess.HasExited)
- continue;
- }
- else
- continue;
- try
- {
- _runningProcess.Kill();
- Thread.Sleep(200);
- _runningProcess.Refresh();
- if (_runningProcess.HasExited)
- SendErrorMessage(_serverEndPoint, $"Process killed successfully");
- else
- SendErrorMessage(_serverEndPoint, $"Failed to kill the process");
- }
- catch (Exception e)
- {
- SendErrorMessage(_serverEndPoint, $"Failed to kill the process: {e}");
- }
- _runningProcess = null;
- }
- // Run with transfer
- else if (id == 0xC5 && !IsServer)
- {
- if (_runningProcess != null)
- {
- _runningProcess.Refresh();
- if (!_runningProcess.HasExited)
- continue;
- }
- using (var s = new MemoryStream(result.Buffer))
- {
- var b = new BinaryReader(s);
- b.ReadByte(); // Packet id
- int port = b.ReadInt32();
- Thread.Sleep(300);
- _serverEndPoint = result.RemoteEndPoint;
- var transferer = new FileTransferer();
- transferer.LogMessage += (sender, msg) => Log($"FT: {msg}");
- var files = transferer.ReceiveFiles(new IPEndPoint(_serverEndPoint.Address, port));
- var filename = b.ReadString();
- var arguments = b.ReadString();
- var targetDir = "downloaded";
- foreach (var file in files)
- {
- Directory.CreateDirectory(Path.Combine(targetDir, Path.GetDirectoryName(file.Item1)));
- File.WriteAllBytes(Path.Combine(targetDir, file.Item1), file.Item2);
- }
- filename = Path.Combine(targetDir, filename);
- Log($"{result.RemoteEndPoint} requests process start: {filename} {arguments}");
- _serverEndPoint = result.RemoteEndPoint;
- try
- {
- _runningProcess = Process.Start(filename,
- arguments.Replace("{IP}", _serverEndPoint.Address.ToString()));
- Thread.Sleep(300);
- _runningProcess.Refresh();
- if (_runningProcess.HasExited)
- {
- SendErrorMessage(_serverEndPoint,
- $"Process creation failed with exit code: {_runningProcess.ExitCode}");
- Log($"Process creation failed with exit code: {_runningProcess.ExitCode}");
- }
- }
- catch (Exception e)
- {
- Log($"{e}");
- SendErrorMessage(_serverEndPoint, $"Process creation failed: {e}");
- }
- }
- }
- }
- catch (Exception e)
- {
- }
- }
- }
- private async Task SenderThreadFunc()
- {
- while (true)
- {
- try
- {
- bool any;
- lock (_sendQueue)
- any = _sendQueue.Any();
- if (any)
- {
- Message msg;
- lock (_sendQueue)
- msg = _sendQueue.Dequeue();
- await _client.SendAsync(msg.Data, msg.Data.Length, msg.EndPoint);
- //Log($"Sent data to {msg.EndPoint}");
- }
- else
- await Task.Delay(10);
- }
- catch (Exception e)
- {
- }
- }
- }
- private async Task DiscoverThreadFunc()
- {
- while (true)
- {
- try
- {
- lock (_sendQueue)
- {
- // Sala 10
- _sendQueue.Enqueue(new Message()
- {
- EndPoint = new IPEndPoint(
- IPAddress.Parse("192.168.4.143"),
- Port),
- Data = new byte[] { 0xC0 },
- });
- foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
- {
- if ((ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 ||
- ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet) &&
- ni.OperationalStatus == OperationalStatus.Up)
- {
- foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
- {
- if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
- {
- var broadcastIp = ip.Address.GetAddressBytes();
- for (int i = 0; i < 4; i++)
- if (ip.IPv4Mask.GetAddressBytes()[i] == 0)
- broadcastIp[i] |= 0xFF;
- _sendQueue.Enqueue(new Message()
- {
- EndPoint = new IPEndPoint(
- new IPAddress(broadcastIp),
- Port),
- Data = new byte[] { 0xC0 },
- });
- }
- }
- }
- }
- }
- // Check timeouts
- Peer[] peers;
- lock (_peers)
- peers = _peers.ToArray();
- foreach (var peer in peers)
- {
- if (DateTime.Now > peer.LastAlive.AddMilliseconds(Timeout))
- {
- _peers.Remove(peer);
- PeerDisconnected?.Invoke(this, peer);
- Log($"{peer.EndPoint} disconnected");
- }
- }
- }
- catch (Exception e)
- {
- }
- await Task.Delay(1000);
- }
- }
- public EventHandler<string> LogMessage;
- private void Log(string message)
- {
- LogMessage?.Invoke(this, message);
- }
- private void SendComputerInfo(IPEndPoint endPoint)
- {
- var s = new MemoryStream();
- var b = new BinaryWriter(s);
- b.Write((byte)0xC1);
- b.Write(Environment.MachineName);
- if (_runningProcess != null)
- _runningProcess.Refresh();
- b.Write(!_runningProcess?.HasExited ?? false);
- SendMessage(new Message()
- {
- EndPoint = endPoint,
- Data = s.ToArray(),
- });
- //Log($"Sending computer info to {endPoint}");
- }
- private void SendMessage(Message msg)
- {
- lock (_sendQueue)
- _sendQueue.Enqueue(msg);
- }
- private void SendErrorMessage(IPEndPoint endPoint, string message)
- {
- var s = new MemoryStream();
- var b = new BinaryWriter(s);
- b.Write((byte)0xC2);
- b.Write(message);
- SendMessage(new Message()
- {
- EndPoint = endPoint,
- Data = s.ToArray(),
- });
- }
- public void SendProcessStart(string filename, string args)
- {
- var r = new Random();
- var s = new MemoryStream();
- var b = new BinaryWriter(s);
- b.Write((byte)0xC3);
- b.Write(filename);
- b.Write(args.Replace("{RANDOM}", "" + r.Next(10000, 99999)));
- lock (_peers)
- foreach (var peer in _peers)
- {
- SendMessage(new Message()
- {
- EndPoint = peer.EndPoint,
- Data = s.ToArray(),
- });
- }
- }
- public async Task SendProcessStartWithFiles(string filename, string args)
- {
- var r = new Random();
- var transferer = new FileTransferer();
- transferer.LogMessage += (sender, msg) => Log($"FT: {msg}");
- try
- {
- var mainDir = Path.GetDirectoryName(filename);
- var files = new List<string>();
- foreach (var file in Directory.GetFileSystemEntries(mainDir, "*", SearchOption.AllDirectories))
- if (!Directory.Exists(file))
- files.Add(file);
- transferer.Start(files.ToArray());
- }
- catch (Exception e)
- {
- MessageBox.Show($"Failed to send files: {e}", "ClusterX", MessageBoxButton.OK, MessageBoxImage.Error);
- return;
- }
- Thread.Sleep(100);
- var s = new MemoryStream();
- var b = new BinaryWriter(s);
- b.Write((byte)0xC5);
- b.Write(transferer.Port);
- b.Write(filename);
- b.Write(args.Replace("{RANDOM}", "" + r.Next(10000, 99999)));
- lock (_peers)
- foreach (var peer in _peers)
- {
- SendMessage(new Message()
- {
- EndPoint = peer.EndPoint,
- Data = s.ToArray(),
- });
- }
- }
- public async Task SendProcessKill()
- {
- var s = new MemoryStream();
- var b = new BinaryWriter(s);
- b.Write((byte)0xC4);
- lock (_peers)
- foreach (var peer in _peers)
- {
- SendMessage(new Message()
- {
- EndPoint = peer.EndPoint,
- Data = s.ToArray(),
- });
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment