Клиент должен подключиться к фабрике, отправить как парольную фразу, сервер тоже ее сравнивает. После этого сервер должен отправить датапак (удаленный сброс). После этого все должно закрыться. Сервер по-прежнему должен принимать другие запросы на подключение.
Я попробовал список задач, но не смог заставить его работать. Я даже не могу заставить асинхронную работу работать. Есть какие-нибудь советы?
Этот скрипт — мой новейший клиентский скрипт:
Код: Выделить всё
class UDPClient : IDisposable
{
public static bool messageReceived = false;
public const int listenPort = 11000;
public byte[] firstMessage = Encoding.ASCII.GetBytes("I heard you");
public byte[] firstCond = Encoding.ASCII.GetBytes("Send Login Data");
public AsyncCallback checkConnectionCB = new AsyncCallback(CheckConnection);
public struct UdpState
{
public UdpClient listenerMaster; //u
public IPEndPoint customerMaster; // e
}
static void Main()
{
UDPClient start = new UDPClient();
start.StartListener();
}
public void Dispose()
{
throw new NotImplementedException();
}
// Send message to customer here (eg Login)
// send data package if ok
public void StartListener()
{
UdpClient listener = new UdpClient();
IPEndPoint customer = new IPEndPoint(IPAddress.Any, listenPort);
listener.Connect(customer);
listener.DontFragment = true;
Console.WriteLine("Connecting to factory (StartListener)");
// Wait for customer ip and port
// save customer ip and port so listener can open new line
listener.Connect(customer);
Console.WriteLine("Connecting to customer");
try
{
listener.BeginSend(firstMessage, firstMessage.Length, checkConnectionCB, firstCond);
}
catch (SocketException e)
{
Console.WriteLine(e);
}
}
public static void CheckConnection(IAsyncResult resultConnection)
{
Console.WriteLine("CheckConnection IAsyncREsult sollte kommen");
}
}
РЕДАКТИРОВАТЬ:
изменил мой код (серверная/заводская сторона), остались вопросы
Сейчас попробовал заводскую сторону. Он должен прослушивать любой IP позже. Теперь у меня нет точки входа, кроме использования static async void Main().
Я почувствовал, что есть серьезные ошибки, но каким-то образом мне удалось это сделать: Visual Studio не выдает много ошибок.Мои вопросы:
- Как мне сказать, что метод Main() является отправной точкой? Каким-то образом это сработало с моим старым кодом...
- Как мне запустить его, когда кто-то с ним связывается и где мне открыть еще один прослушиватель чтобы он мог получить еще один запрос во время работы над первым?
- Открывает ли он разные прослушиватели или для списка задач он всегда один и тот же? ?
}
Код: Выделить всё
using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Net; using System.Text; using System.Threading.Tasks; using System.Net.NetworkInformation; using System.Runtime.CompilerServices; using System.Security.Cryptography.X509Certificates; namespace Factory { // CHANGE: Customer IP to Any IP // CHANGE: customer Port to Any Port class FactoryUDP : UdpClient, IDisposable { public bool IsCompleted { get; } public const int listenPort = 11000; public static bool isConnected; public static bool messageReceived; public string testData = "UserName PassWord"; public byte[] message1 = Encoding.ASCII.GetBytes("Please write user name and password, separated with one space and hit enter."); public object? sendOne; public IAsyncResult? loginAsyncResult; static async void Main() { Console.WriteLine("Starting Main"); FactoryUDP start = new FactoryUDP(); start.RemoteReset(); // await/ return / something; } public struct UdpState { public UdpClient u; //listener public IPEndPoint e; //customer } /* public void Dispose() { throw new NotImplementedException(); } */ public async Task RemoteReset() { var connectionTask = ConnectCustomer(); var loginTask = LoginRequest(); var sendRemoteTask = SendRemoteReset(); var closeTask = CloseEverything(); await connectionTask; await loginTask; await sendRemoteTask; var remoteTasks = new List { connectionTask, loginTask, sendRemoteTask }; while (remoteTasks.Count > 0) { Task finishedTask = await Task.WhenAny(remoteTasks); if (finishedTask == connectionTask) { Console.WriteLine("ConnectionTask finished"); } else if (finishedTask == loginTask) { Console.WriteLine("LoginTask finished"); } else if (finishedTask == sendRemoteTask) { Console.WriteLine("Send remote Task finished"); } await finishedTask; Console.WriteLine($"Task isCompleted state: {IsCompleted}"); await Task.WhenAll(remoteTasks.ToArray()); // remoteTasks.Remove(finishedTask); // Task list: wait for all remoteTasks and then CloseEverything(); } async Task ConnectCustomer() { UdpClient u = new UdpClient(listenPort); IPEndPoint e = new IPEndPoint(IPAddress.Any, listenPort); u.Connect(e); u.DontFragment = true; isConnected = true; u.BeginReceive(ReceiveCallback1, e); // EndReceive in ReceiveCallback1 Console.WriteLine("BeginReceive - ReceiveCallback1 in ConnectCustomer"); u.BeginSend(message1, message1.Length, SendCallback1, sendOne); // EndSend in SendCallback1 Console.WriteLine("BeginSend Message1 - SendCallback1 in ConnectCustomer"); // when connected to customer add a new listener to listen for other customers? await ConnectCustomer(); await LoginRequest(); //await LoginCompare(); await SendRemoteReset(); } async Task LoginRequest() { // begin receive, user name and password separated with space? UdpClient u = ((UdpState)loginAsyncResult.AsyncState).u; IPEndPoint e = ((UdpState)loginAsyncResult.AsyncState).e; UdpState s = new UdpState(); s.e = e; s.u = u; u.BeginReceive(new AsyncCallback (ReceiveCallback2), s); byte[] receiveLoginData = u.EndReceive(loginAsyncResult, ref e); string receiveLoginDataString = Encoding.ASCII.GetString(receiveLoginData); Console.WriteLine($"Received Login data: {receiveLoginDataString}"); // separate string to user name (space) password receiveLoginDataString //What to do with the login data? write in j son? if (testData == receiveLoginDataString) { await SendRemoteReset(); Console.WriteLine("Successfully compared testData with receivedString, awaiting SendRemoteReset"); } else { await CloseEverything(); Console.WriteLine("Failed to compare testData with received LoginData. Awaiting CloseEverything"); } //return Task.; await LoginRequest(); } static async Task SendRemoteReset() { Console.WriteLine("SendRemoteReset here (datapack)"); //send remote reset data pack and CloseEverything() await Task.Delay(2); } static async Task CloseEverything() { isConnected = false; Console.WriteLine("CloseEverything here. Waiting for Task.Delay(330)"); await Task.Delay(300); // Close everything and start another listener for customers } static async void ReceiveCallback1(IAsyncResult ar1) { UdpClient u = ((UdpState)ar1.AsyncState).u; IPEndPoint e = ((UdpState)ar1.AsyncState).e; byte[] receiveBytes = u.EndReceive(ar1, ref e); string receiveString = Encoding.ASCII.GetString(receiveBytes); Console.WriteLine($"Received: {receiveString}"); messageReceived = true; Console.WriteLine("Setting messageReceived to true"); return; } // public delegate here? async void SendCallback1(IAsyncResult? sendOne) { UdpClient u = ((UdpState)sendOne.AsyncState).u; IPEndPoint e = ((UdpState)sendOne.AsyncState).e; u.EndSend(sendOne); Console.WriteLine("EndSend ind SendCallback1 here"); await LoginRequest(); } async void ReceiveCallback2(IAsyncResult? loginAsyncResult) { UdpClient u = ((UdpState)loginAsyncResult.AsyncState).u; IPEndPoint e = ((UdpState)loginAsyncResult.AsyncState).e; byte[] receiveLoginData = u.EndReceive(loginAsyncResult, ref e); string receiveLoginDataString = Encoding.ASCII.GetString(receiveLoginData); Console.WriteLine($"Received Login data: {receiveLoginDataString}"); return; // go to LoginRequest from here? } } }
Я переписал снова написал код, снова многому научился, но все еще не могу заставить сервер и клиент взаимодействовать друг с другом...
сторона сервера:
Код: Выделить всё
class FactoryUDP : UdpClient, IDisposable
{
// https://stackoverflow.com/questions/7266101/receive-messages-continuously-using-udpclient
public bool IsCompleted { get; }
public byte[] factoryIP = new byte[] { 127, 0, 0, 1 }; // line 83/84 //ToDo.MG rewrite for any IP and remove
public const int listenPort = 11000; //ToDo.MG rewrite for any IP and remove
public static bool isConnected;
public static bool messageReceived;
public string testData = "UserName PassWord"; //ToDo.MG rewrite and remove
public string? receiveLoginDataString;
public byte[] message1 = Encoding.ASCII.GetBytes("Please write user name and password, separated with one space and hit enter."); //ToDo.MG rewrite and remove
public object? sendOne;
public object? loginAsyncResult;
public object? cusConnSuccess;
//private static bool IsNotNull1([NotNullWhen(true)] object? cusConnSucc) => cusConnSucc != null;
//private static bool IsNotNull2([NotNullWhen(true)] object? sendOne) => sendOne != null;
static void Main()
{
FactoryUDP start = new FactoryUDP();
start.MainAsync().Wait();
}
public async Task MainAsync()
{
UdpClient uMaster = new UdpClient(listenPort);
IPEndPoint eMaster = new IPEndPoint(new IPAddress(factoryIP), listenPort);
var connectionTask = ConnectCustomer();
var loginTask = LoginRequest();
var sendRemoteTask = SendRemoteReset();
var closeTask = CloseEverything();
await connectionTask;
await loginTask;
await sendRemoteTask;
await closeTask;
var remoteTasks = new List { connectionTask, loginTask, sendRemoteTask, closeTask };
while (remoteTasks.Count > 0)
{
Console.WriteLine("Task List here");
Task finishedTask = await Task.WhenAny(remoteTasks);
if (finishedTask == connectionTask)
{
Console.WriteLine("ConnectionTask finished");
}
else if (finishedTask == loginTask)
{
Console.WriteLine("LoginTask finished");
}
else if (finishedTask == sendRemoteTask)
{
Console.WriteLine("Send remote Task finished");
}
else if (finishedTask == closeTask)
{
Console.WriteLine("Send close Task finished");
}
await finishedTask;
Console.WriteLine($"Task isCompleted state: {IsCompleted}");
await Task.WhenAll();
}
async void ReceiveCallback1(IAsyncResult cusConnSucc)
{
Console.WriteLine("BeginReceive - ReceiveCallback1 in ConnectCustomer");
isConnected = true;
byte[] receiveBytes = uMaster.EndReceive(cusConnSucc, ref eMaster);
string receiveString = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine($"Received in ReceiveCallback1: {receiveString}");
bool connectMessage = receiveBytes.Equals(Encoding.ASCII.GetBytes("Factory! Listen!"));
Console.WriteLine($"Received bytes from Gripper: {connectMessage}");
if (connectMessage == true && isConnected)
{
messageReceived = true;
Console.WriteLine("Setting messageReceived to true (only if isConnected is also true).");
// AsyncCallback callbackCustomerConnect = new AsyncCallback(LoginRequest);
}
else
{
Console.WriteLine("Something went wrong with compare connectMessage");
await CloseEverything();
}
cusConnSucc.AsyncWaitHandle.WaitOne();
}
async void SendCallback1(IAsyncResult sendOne)
{
Console.WriteLine("BeginSend Message1 - SendCallback1 in ConnectCustomer");
uMaster.EndSend(sendOne);
Console.WriteLine("EndSend in SendCallback1 here");
sendOne.AsyncWaitHandle.WaitOne();
}
async void ReceiveCallback2(IAsyncResult? loginAsyncResult)
{
Console.WriteLine("BeginReceive - Callback 2 in LoginRequest");
byte[] receiveLoginData = uMaster.EndReceive(loginAsyncResult, ref eMaster);
string receiveLoginDataString = Encoding.ASCII.GetString(receiveLoginData);
Console.WriteLine($"Received Login data: {receiveLoginDataString}");
loginAsyncResult.AsyncWaitHandle.WaitOne();
}
async Task ConnectCustomer()
{
uMaster.Connect(eMaster);
Console.WriteLine("Task ConnectCustomer BeginReceive, BeginSend, BeginReceive which are just laying here");
uMaster.BeginReceive(ReceiveCallback1, cusConnSuccess);
uMaster.BeginSend(message1, message1.Length, SendCallback1, sendOne);
uMaster.BeginReceive(ReceiveCallback2, loginAsyncResult);
await ConnectCustomer();
}
async Task LoginRequest()
{
bool login = receiveLoginDataString.Equals(testData);
if (login == true)
{
Console.WriteLine("login = true, next is SendRemoteReset");
await SendRemoteReset();
}
else
{
Console.WriteLine("LoginRequest, login false");
await CloseEverything();
}
}
async Task SendRemoteReset()
{
Console.WriteLine("SendRemoteReset here (data pack), now TaskDelay(300) in SendRemoteTask");
await Task.Delay(300);
}
async Task CloseEverything()
{
isConnected = false;
Console.WriteLine("CloseEverything here. Waiting for Task.Delay(600)");
await Task.Delay(600);
Console.WriteLine("Closing Everything last line.");
Console.WriteLine("Continue with any Key here, so the program stops for a moment");
Console.ReadKey(); // just so it won't repeat all the time
}
}
}
Код: Выделить всё
class GripperUDP : UdpClient, IDisposable
{
public bool IsCompleted { get; }
public static bool isConnected;
object sendFirst;
object receiveOne;
object logDataState;
public const int listenPort = 11001;
public byte[] factoryIP = new byte[] { 127, 0, 0, 1 };
public string compareLoginData = "UserName PassWord";
public byte[] connectMessage = Encoding.ASCII.GetBytes("Factory! Listen!");
static void Main()
{
GripperUDP start = new GripperUDP();
start.MainAsync().Wait();
}
public async Task MainAsync()
{
UdpClient uMaster = new UdpClient(listenPort);
IPEndPoint eMaster = new IPEndPoint(new IPAddress(factoryIP), listenPort);
var connectionTask = ConnectFactory();
var receiveRemoteTask = ReceiveRemoteReset();
var closeTask = CloseEverything();
await connectionTask;
await receiveRemoteTask;
var remoteTasks = new List { connectionTask, receiveRemoteTask, closeTask };
while (remoteTasks.Count > 0)
{
Task finishedTask = await Task.WhenAny(remoteTasks);
if (finishedTask == connectionTask)
{
Console.WriteLine("ConnectionTask finished");
}
else if (finishedTask == receiveRemoteTask)
{
Console.WriteLine("Receive remote Task finished");
}
else if (finishedTask == closeTask)
{
Console.WriteLine("Close Task finished");
}
await finishedTask;
Console.WriteLine($"Task isCompleted state: {IsCompleted}");
await Task.WhenAll(remoteTasks.ToArray());
// remoteTasks.Remove(finishedTask);
}
async void SendCallback1(IAsyncResult? sendFirstObject)
{
if (sendFirstObject != null)
{
uMaster.EndSend(sendFirstObject);
Console.WriteLine("EndSend in SendCallback1 here");
sendFirstObject.AsyncWaitHandle.WaitOne();
}
else
{
Console.WriteLine("sendFirst is null exception. Closing with uMaster.Close.");
uMaster.Close();
}
}
async void ReceiveCallback1(IAsyncResult received)
{
if (received != null)
{
byte[] receivedBytes = uMaster.EndReceive(received, ref eMaster!);
string receivedString = Encoding.ASCII.GetString(receivedBytes);
bool receivedMessageFactory = receivedBytes.Equals(Encoding.ASCII.GetBytes("Please write user name and password, separated with one space and hit enter."));
Console.WriteLine($"Received: {receivedString}");
if (receivedMessageFactory == true)
{
Console.WriteLine("received loginRequestMessage from factory. forwarding to LoginRequest");
uMaster.BeginReceive(ReceiveCallback2, logDataState);
Console.WriteLine("Begin ReceiveCallBack 2");
received.AsyncWaitHandle.WaitOne();
}
else
{
Console.WriteLine("Wrong factory message received. now uMaster.Close();");
uMaster.Close();
}
}
}
async void ReceiveCallback2(IAsyncResult callBack2Object)
{
if (callBack2Object != null)
{
byte[] receivedLoginData = uMaster.EndReceive(callBack2Object, ref eMaster!);
string loginInfo = receivedLoginData.ToString();
Console.WriteLine("receivedLoginData converted to String, comparing next");
bool loginCheck = loginInfo.Equals(compareLoginData);
if (receivedLoginData != null)
{
if (loginCheck == true)
{
Console.WriteLine("LoginCheck successful");
callBack2Object.AsyncWaitHandle.WaitOne();
await ReceiveRemoteReset();
}
else
{
Console.WriteLine("Login Check/compare went wrong. Now uMaster.Close();");
uMaster.Close();
}
}
else
{
Console.WriteLine("Something went wrong in LoginRequest / comparing. Closing with uMaster.Clsoe()");
uMaster.Close();
}
callBack2Object.AsyncWaitHandle.WaitOne();
}
}
async Task ConnectFactory()
{
uMaster.Connect(eMaster);
isConnected = true;
uMaster.BeginReceive(ReceiveCallback1, receiveOne);
Console.WriteLine("First beginReceive");
uMaster.BeginSend(connectMessage, connectMessage.Length, SendCallback1, sendFirst);
Console.WriteLine("First beginSend");
await ReceiveRemoteReset();
}
static async Task CloseEverything()
{
isConnected = false;
Console.WriteLine("CloseEverything here. Waiting for Task.Delay(200) in same method");
await Task.Delay(200);
Console.WriteLine("Closing Everything after Delay (ReadKey) for waiting");
Console.ReadLine();
}
static async Task ReceiveRemoteReset()
{
if (isConnected == true)
{
Console.WriteLine("Waiting Task Delay (600) of ReceiveRemoteReset.)");
await Task.Delay(600);
Console.WriteLine("Task.Dealy(600) over. CloseEverything()");
await CloseEverything();
}
else
{
Console.WriteLine("ReceiveRemoteReset, isConnected false CloseEverything()");
await CloseEverything();
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/787 ... munication
Мобильная версия