Задержка прослушивания сокетов .NET

У меня есть серверный сокет, который я настроил для одновременного разрешения одного соединения (путем блокировки вызовов Accept с помощью семафора) с размером очереди невыполненных работ, равным 1. То есть я вызвал .Listen(1).

Затем я следую следующему процессу:

  • Я вызываю AcceptAsync на сокете моего сервера (только один раз)
  • У меня есть клиент ConnectAsync (успешно подключается)
  • У меня есть клиент ConnectAsync (подключается успешно, якобы в очереди... способ сказать было бы неплохо)
  • У меня есть третий клиент ConnectAsync

Эти три вызова ConnectAsync происходят в быстрой последовательности.

Ожидаемый результат для третьего ConnectAsync — свойство SocketAsyncEventArgs «SocketError» будет отличаться от «SocketError.Success». Я действительно ожидаю, что "SocketError.ConnectionRefused" будет конкретным.

Примерно в 95% случаев так оно и есть. Обратный вызов третьего клиента дает мне значение SocketError, отличное от Success.

Однако время от времени третий ConnectAsync «работает» так же, как и второй. EventArgs.SocketError дает мне SocketError.Success, а соответствующее свойство Socket.Connected имеет значение «true».

Что происходит? Я вызываю AcceptAsync ровно один раз (я тщательно проверил это с помощью точек останова), поэтому должен быть принят только один клиент, а остальные должны быть в очереди невыполненных работ. Размер моей очереди равен 1, так как же время от времени успешно подключается третий клиент?

Пожалуйста, не говорите мне использовать очередь большего размера. Это для тестовой функции, которую я написал, а не для кода, который активно обслуживает клиентов. На данный момент это больше любопытство. :)


person Sapph    schedule 08.01.2011    source источник
comment
Может быть, ваше второе ожидающее соединение было закрыто (во время отладки) и появилось место для еще одного соединения?   -  person Eugene Mayevski 'Callback    schedule 08.01.2011
comment
Я так не думаю. У меня есть точка останова, которая срабатывает через 5 секунд после попытки подключения. В этот момент, если я проверю все три сокета, для всех трех .Connected установлено значение true.   -  person Sapph    schedule 09.01.2011


Ответы (1)


Это не сработает. Система повысит ваш список невыполненных прослушиваний с 1 до собственного минимума, который будет составлять не менее 50.

Просто сделайте свой сервер однопоточным. Тогда он будет обрабатывать только одно соединение за раз. Последующие подключения будут ожидать в очереди невыполненных работ. Когда очередь невыполненных работ заполнена, они получат сообщение об отказе в подключении, если сервер является платформой Windows. Не иначе.

person user207421    schedule 10.01.2011
comment
Только, это работает, почти каждый раз. Тест терпит неудачу только иногда. Я спрашиваю, какие обстоятельства приводят к его отказу. Как я уже сказал, я не заинтересован в запуске такого рода серверов в производственной среде. Вопрос в том, чтобы удовлетворить собственное любопытство. - person Sapph; 13.01.2011
comment
@Sapph: это может сработать, но не по этой причине. Минимальное значение отставания в Windows равно 5 (спецификация Winsock). И вряд ли можно назвать успехом «провалы лишь изредка». - person user207421; 14.02.2011
comment
Хорошо, а мы можем попытаться выяснить, почему это работает большую часть времени? Пытается ли платформа .NET установить отдельное ограничение на программное обеспечение независимо от спецификации ОС? Почему это своего рода весь смысл этого вопроса. :) - person Sapph; 15.02.2011
comment
Я не могу комментировать .NET framework или почему ваш код работает именно так, не видя его. - person user207421; 15.02.2011