Вопрос по SocketAsyncEventArgs (SAEA)

#c# #sockets

#c# #сокеты

Вопрос:

Я внедрил асинхронное соединение с сокетом, и оно успешно взаимодействует с клиентом. Проблема, с которой я в настоящее время сталкиваюсь, заключается в отправке пакетов клиенту по таймеру, независимому от определенного протокола.

Каждый раз, когда я вызываю SAEA.Принимает Socket.SendAsync(…) Я получаю исключение: System.Исключение InvalidOperationException: «Асинхронная операция сокета уже выполняется с использованием этого экземпляра SocketAsyncEventArgs».

Я провел некоторое тестирование и, похоже, не могу вызвать SAEA.Принимает Socket.Отправляйте синхронизацию (…) сразу одну за другой. Так ли разработан SAEA, или я делаю что-то не так в своем коде, что вызывает возникновение исключения?

Я потратил немного времени на поиск в Google, но, похоже, не могу найти никаких ответов. Если бы кто-нибудь мог мне помочь или, по крайней мере, указать мне правильное направление, я был бы очень признателен!

Спасибо!

Ответ №1:

Для каждого экземпляра SocketAsyncEventArgs может быть отложена только одна операция. Вам либо нужно дождаться завершения текущей операции, либо просто использовать уникальный экземпляр SocketAsyncEventArgs для каждой отправки.

Комментарии:

1. Как вы создаете уникальный экземпляр, когда SocketAsyncEventArgs создается на основе завершения Accept, таким образом, действительно имея по одному SocketAsyncEventArgs на клиента?

2. Вы создаете SocketAsyncEventArgs для вашего первоначального вызова Accept Sync, передаете его этому и в конечном итоге, когда вызов завершается, вы получаете его обратно… Затем вы можете либо повторно использовать его, либо создать новый для следующей асинхронной операции, которую вам нужно выполнить…

3. Спасибо, если ваше предложение приведет меня на правильный путь. Я действительно использовал уникальный экземпляр SocketAsyncEventArgs и использовал сокет из другого SocketAsyncEventArgs для отправки тому же клиенту. Исключение, которое я получил, было связано с тем, что SocketAsyncEventArg использовался одновременно, но, похоже, можно использовать один и тот же AcceptSocket между двумя или более SocketAsyncEventArgs.

Ответ №2:

Каждый раз, когда вы отправляете сообщение повторно, оно будет пытаться отправить или ждать до истечения времени ожидания или ошибки.
Возможно, с вами произошло то, что вы все еще обрабатываете предыдущее сообщение и попытались отправить его снова, используя те же SocketAsyncEventArgs. Если SocketAsyncEventArgs ожидает следующего процесса, то, попросив его перейти к другому процессу, вы получите эту ошибку.

Итак, если слушателем является сервер, когда клиент пытается отправить, я бы посоветовал вам установить новое соединение и создать для него новый SocketAsyncEventArgs.

Комментарии:

1. Привет, C_Rance, это нормально для установления новых подключений, это когда я пытаюсь отправить пакет, но вы, вероятно, правы в том, что SocketAsyncEventArgs все еще обрабатывает предыдущую отправку, когда я пытаюсь отправить другую.

Ответ №3:

я думаю, вам нужно вызвать SAEA.Принимает Socket.Сначала завершите прием (…), чтобы завершить процесс асинхронного подключения или SAEA.Принимает Socket.Завершает отправку (…), чтобы завершить предыдущую отправку

Комментарии:

1. Когда вы говорите end, это прерывается или завершается? Потому что я бы не хотел, чтобы какие-либо пакеты не отправлялись.

2. EndSend (..) завершит операцию и отправит данные

3. EndAccept используется только в паре с BeginAccept, а не с Accept sync или объектом SocketAsyncEventArgs.