C# асинхронное прослушивание сокета в проекте WinForms
Идея
Существует некоторое приложение (WinForms), к которому необходимо подключить что-то вроде сервера. Я пытался засунуть в данное приложение консоль, но после некоторого потраченного времени на изучение данного вопроса, пришел к выводу, что этого делать не стоит, а будет лучше подключить новую форму и там обрабатывать все что нужно (если есть комментарии по этому поводу, я внимательно вас читаю).
Многопоточность
Так вот, самая первая проблема возникла в ходе проб и ошибок, когда запущенное окно блокировало родительское на этапе прослушивания клиента. Ну и собственно в голову пришло изучение и использование многопоточности, а т.к. я не являюсь его знатоком, то тут начало возникать куча проблем. Опишу 2 из них, которые значительно усложняют мою задачу:
- (опционально, вы можете пропустить данную проблему) В форме-сервере находится RixhBoxText, который выводит промежуточные данные о записях или принятых данных. При попытке запустить метод следующим способом:
Thread myThread = new Thread(new ThreadStart(Listen())); myThread.Start();выкидывает ошибку о том, что нельзя изменять RichBoxText в других потоках, кроме самого потока формы. - В данной статье, вроде, нашел решение своей проблемы. Создание сокета происходит так:
private Socket listener = null;
private IPEndPoint ipPoint = null;
private void Server_Load(object sender, EventArgs e)
{
// create listener with console app
this.ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
this.listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(ipPoint);
listener.Listen(10);
}
catch (Exception ex)
{
bufferAfterLoad = ex.Message;
}
//if normal connected, say about it
newMainForm.ServerOn();
}
Далее, после выводы формы, запускаем метод прослушки:
private void Server_Shown(object sender, EventArgs e)
{
if (bufferAfterLoad != null)
Print(bufferAfterLoad);
Listen();
}
async private void Listen()
{
Print($"Connected to {serialNum} device!");
try
{
var handler = await listener.AcceptAsync(); // ЗДЕСЬ ВЫДАЕТ ОШИБКУ!!!
while (true)
{
//Receive message.
var buffer = new byte[1_024];
var received = await handler.ReceiveAsync(buffer, SocketFlags.None);
var response = Encoding.UTF8.GetString(buffer, 0, received);
var eom = "<|EOM|>";
if (response.IndexOf(eom) > -1 /* is end of message */)
{
Print($"Socket server received message: \"{response.Replace(eom, "")}\"");
var ackMessage = "<|ACK|>";
var echoBytes = Encoding.UTF8.GetBytes(ackMessage);
await handler.SendAsync(echoBytes, 0);
Print($"Socket server sent acknowledgment: \"{ackMessage}\"");
break;
}
// Sample output:
// Socket server received message: "Hi friends ?!"
// Socket server sent acknowledgment: "<|ACK|>"
}
}
catch (Exception ex)
{
Print(ex.Message);
Print("Wait for closing...");
Thread.Sleep(5 * 1000);
this.Close();
}
}
Ну и собственно сама ошибка: Отсутствует аргумент, соответствующий требуемому формальному параметру "e" из "Socket.AcceptAsync(SocketAsyncEventArgs)".
PS
Если есть какие-то замечания или идеи по данной ситуации, я внимательно вас читаю :) Дочитавшим до конца - спасибо за терпение!