WIN32 Socket API: Отмена отправки / записи в сокет с использованием уведомлений о завершении на основе событий

С помощью сокета с перекрывающейся операцией выбирается уведомление о завершении на основе события; Есть 2 события, одно для данных, другое для отмены длительной отправки / записи:

 HANDLE events[] = { m_hDataEvent, m_hInterruptEvent };

затем вызывая WSASend,

 WSASend(m_Socket, &DataBuf, 1, NULL, 0, &SendOverlapped, NULL);

с последующим

 WSAWaitForMultipleEvents(2, events, FALSE, INFINITE, FALSE);

который настроен так, чтобы возвращаться при любом сигнальном событии. Теперь предположим, что отправка выполняется, и m_hInterruptEvent сигнализируется. Возвращает WSAWaitForMultipleEvents, технически функция, вызывающая send, также может возвращать и удалять внутренние буферы.

Что мне не понятно, WSASend может все еще работать в фоновом режиме, и удаление буферов в лучшем случае приведет к повреждению данных.

Каков был бы правильный способ остановить фоновую отправку / получение, если необходимо немедленно использовать сокет для чего-то другого?

Я посмотрел на CancelIO(), но MSDN никогда не упоминает его в отношении сокетов, работает ли он только с файловым вводом-выводом?

1 ответ

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

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

  • Отправьте кусками и проверьте отмену между кусками. Убедитесь, что у вас есть способ сообщить получателю, что передача была отменена.
  • Закройте сокет, чтобы отменить. Опять же, убедитесь, что у клиента есть способ узнать, что это прерванная передача (например, если клиент заранее знает общую длину, он распознает прерванную передачу).
  • Просто подождите, пока все получится, и не волнуйтесь. Если у вас есть срочные сообщения, используйте для них отдельное соединение.

На ваш конкретный вопрос "Каким будет правильный способ остановить фоновую отправку / получение, если необходимо немедленно использовать сокет для чего-то другого", ответ таков: сокеты дешевы - просто используйте два - один для медленной передачи. посмотри за срочными сообщениями.

Другие вопросы по тегам