public Message StartWorking() { Socket socket = null; string ipAddress = "10.147.20.151"; int port = 8000; try { IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse(ipAddress), port); socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // подключаемся к другому клиенту IAsyncResult result = socket.BeginConnect(ipAddress, port, null, null); bool success = result.AsyncWaitHandle.WaitOne(1000, true); if (socket.Connected) { socket.EndConnect(result); //отправляем клиенту приветствие socket.Send(HelperClass.ObjectToByteArray( new Message { Command = Command.Work, Data = new MessageData { A = 123 } })); return((Message)HelperClass.ByteArrayToObject(HelperClass.RecieveMessage(socket))); } else { socket.Close(); return(null); //throw new ApplicationException("Failed to connect"); } } catch { //Console.WriteLine($"stop working{socket.RemoteEndPoint}"); socket.Close(); return(null); } }
/// <summary> /// Отправляет приветствие другому клиенту /// </summary> /// <param name="ipAddress">ip адрес другого клиента</param> /// <param name="port">порт на котором работает другой клиент</param> /// <returns></returns> /// public bool SendHelloToClient(string ipAddress, int port) { Socket socket = null; try { IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse(ipAddress), port); socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // подключаемся к другому клиенту IAsyncResult result = socket.BeginConnect(ipAddress, port, null, null); bool success = result.AsyncWaitHandle.WaitOne(1000, true); if (socket.Connected) { socket.EndConnect(result); //отправляем клиенту приветствие socket.Send(HelperClass.ObjectToByteArray( new Message { Command = Command.Greeting, Data = new MessageData { A = 123 } })); return((bool)HelperClass.ByteArrayToObject(HelperClass.RecieveMessage(socket))); } else { socket.Close(); return(false); //throw new ApplicationException("Failed to connect"); } } catch { socket.Close(); return(false); } }
private static void ReturnAnswer(object socket) { var clientSocket = socket as Socket; try { var message = (Message)HelperClass.ByteArrayToObject(HelperClass.RecieveMessage(clientSocket)); //string query = site + info + $"&mode={mode}"; //message = ReTry(query); //Console.WriteLine($"{DateTime.Now.ToString(new CultureInfo("ru-RU"))} " + // $"{Thread.CurrentThread.Name} : " + // $"The message is received"); //если пришло сообщение от другого клиента с приветсвием if (message.Command == Command.Greeting) { clientSocket.Send(HelperClass.ObjectToByteArray(true)); var clientIpEndPoint = (IPEndPoint)clientSocket.RemoteEndPoint; Client.otherClients.TryAdd(clientIpEndPoint.Address.ToString(), clientIpEndPoint); } //если пришло сообщение от другого клиента с просьбой решить подзадачу if (message.Command == Command.Work) { //если этот клиент уже решает какую-то подзадачу, то говорим, //что не можем пока брать на выполнение новую подзадачу if (Worker.IsBusy) { clientSocket.Send(HelperClass.ObjectToByteArray( new Answer { DoneWork = false, })); } //иначе начинаем решать новую подзадачу else { //начинаем решать подзадачу var answer = Worker.DoWork(message.Data); //отправляем ответ на подзадачу clientSocket.Send(HelperClass.ObjectToByteArray(answer)); } } } catch (Exception ex) { //Console.WriteLine($"{DateTime.Now.ToString(new CultureInfo("ru-RU"))} " + // $"{Thread.CurrentThread.Name} :" + // ex.Message); Worker.IsBusy = false; //message = "Извените, но на данный момент невозможно получить ответ"; //if (handler != null && handler.Connected) // handler.Send(HelperClass.ObjectToByteArray(message)); } finally { if (clientSocket != null && clientSocket.Connected) { // закрываем сокет clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); } } }
/// <summary> /// Просим другого клиента выполнить часть работы /// </summary> /// <param name="ipAddress">ip адрес другого клиента</param> /// <param name="port">Порт другого клиента</param> /// <param name="messageData">Часть работы</param> void SendPartWorkToClient(string ipAddress, int port, MessageData messageData) { Socket socket = null; try { IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse(ipAddress), port); socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // подключаемся к другому клиенту IAsyncResult result = socket.BeginConnect(ipAddress, port, null, null); bool success = result.AsyncWaitHandle.WaitOne(1000, true); if (socket.Connected) { socket.EndConnect(result); //отправляем клиенту данные для решения задачи socket.Send(HelperClass.ObjectToByteArray( new Message { Command = Command.Work, Data = messageData, })); //добавляем в список сокетов клиентов новый clientsSockets.TryAdd(ipAddress, socket); clientsWorks.TryAdd(ipAddress, messageData); //ждем ответ на подзадачу var answer = (Answer)HelperClass.ByteArrayToObject(HelperClass.RecieveMessage(socket)); if (answer.DoneWork) { answersValues.Add(answer.Value); } CurrentForm.output.BeginInvoke(new InvokeDelegate( () => { CurrentForm.output.Text += $"\nКлиент {ipAddress} решил подзадачу и получил ответ {answer.Value}"; })); Console.WriteLine($"\nКлиент {ipAddress} решил подзадачу и получил ответ {answer.Value}"); } else { //socket.Close(); //CurrentForm.output.BeginInvoke(new InvokeDelegate( //() => //{ // CurrentForm.output.Text += $"\nКлиент {ipAddress} не смог решить свою часть задачи"; //})); //Console.WriteLine($"\nКлиент {ipAddress} не смог решить свою часть задачи"); ////надо переназначить часть работы кому-то другому //MessageData messageData1 = null; //if (clientsWorks.TryGetValue(ipAddress, out messageData1)) // RunPartOwnWork(messageData1); } } catch { socket.Close(); CurrentForm.output.BeginInvoke(new InvokeDelegate( () => { CurrentForm.output.Text += $"\nКлиент {ipAddress} не смог решить свою часть задачи"; })); Console.WriteLine($"\nКлиент {ipAddress} не смог решить свою часть задачи"); //если другой клиент не смог взять задачу на себя MessageData messageData1 = null; if (clientsWorks.TryGetValue(ipAddress, out messageData1)) { //clientsWorks.TryRemove(ipAddress, out messageData1); bool resendedToClient = false; foreach (var otherClientIp in otherClients.Keys) { //если клиент не работает над задачей if (!clientsWorks.ContainsKey(otherClientIp)) { resendedToClient = true; CurrentForm.output.BeginInvoke(new InvokeDelegate( () => { IPEndPoint endPoint = null; otherClients.TryGetValue(otherClientIp, out endPoint); CurrentForm.output.Text += $"\nКлиент {endPoint.Address} взял задачу клиента {ipAddress}"; })); SendPartWorkToClient(otherClientIp, Configs.ClientPort, messageData1); return; } } if (!resendedToClient) { RunPartOwnWork(messageData1); } } } }