Блокируется, когда обе конечные точки выполняют Socket.SendAsync

Итак, я написал это приложение сокет клиент / сервер, которое использует "метод" SocketAsyncEventArgs для выполнения асинхронных сокетов.

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

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

Когда это делается в модульных тестах с использованием mock-объектов (без задержек) для имитации обычных операций с сокетами, все работает хорошо.

Но в реальных ситуациях, используя реальные сокеты, мы получаем своего рода тупик, когда обе конечные точки застряли в операции Socket.SendAsync() (да, она вернула true, синхронно не обрабатывается).

Моя идея состоит в том, что приемный буфер обеих сторон переполнен, и стек tcp больше не подтверждает кадры. (подключен к 127.0.0.1)

Поэтому я увеличил приемный буфер вдвое по сравнению с sendbuffer, но, к сожалению, это не так просто из-за характера нашего "протокола" и того, как мы определяем отправку или получение.

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

Осложняющим фактором является то, что целью этого соединения является мультиплексирование нескольких двунаправленных каналов связи общего назначения через это сокетное соединение. Это означает, что нет заранее определенной последовательности связи, все каналы могут иметь свои собственные протоколы.

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

После каждой операции я проверяю, есть ли ожидающие данные в приемном буфере или проверяя Socket.Available.

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

Теперь я понимаю, что это неправильно.

Пытаюсь ли я выполнить что-то, что просто невозможно, используя только одно сокетное соединение?

Любой, кто пытался сделать что-то похожее, или знает хороший способ сделать безопасный способ, который не вводит эти странные блокировки.

Спасибо Тео.

0 ответов

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