Я не знаю C#, но я действительно знаю UNIX-сокеты. Моя первая мысль заключалась в том, что вы не вызывали accept() в сокете, прежде чем выбирать для чтения, но (и это доказательство, которое я знаю меньше о сокетах, чем я думал) вы можете выбрать в состоянии прослушивания, чтобы посмотреть, какие сокеты могут быть приняты. Ну хорошо, мы живем и учиться, даже в моем преклонном возрасте :-)
Во всяком случае, ссылаясь на документы MSDN here, найденных через Google с («C#» гнездо привязывать слушать выбор), он заявляет:
If you receive a SocketException, use SocketException.ErrorCode to obtain the specific error code. Once you have obtained this code, you can refer to the Windows Socket Version 2 API error code documentation in MSDN for a detailed description of the error.
Эти коды ошибок, как представляется, задокументированы here, найденные с помощью поиска Google (документация кода ошибки API для Windows Socket Version 2 в MSDN).
Я упоминаю условия поиска Google, если MSDN перемещает их страницы. Я бы вывел код ошибки из обнаруженного исключения, а затем просмотрел его в списке на этой второй ссылке, чтобы получить фактическую причину сбоя. Как только мы это узнаем, мы сможем помочь вам дальше (или это может стать ослепительно очевидным до такой степени, что вам не нужно снова спрашивать нас :-).
Одна вещь, которая кажется несоответствующей: прототип вызова имеет четвертый аргумент, количество микросекунд, чтобы ждать, если нет активности. У вашего кода в вопросе этого нет. Теперь, как я уже сказал, я мало знаю о C#, поэтому он может по умолчанию что-то (или, может быть, вы просто оставили его с вопросом случайно).
Но я бы наблюдал за известной ошибкой, если вы используете -1 (или по умолчанию - -1): см. here, но в основном это означает, что -1 возвращает сразу, а не ждет навсегда. Обходным путем является использование -2, чтобы дать вам час или около того, но вам все равно придется обслуживать тот факт, что он может вернуться, хотя активности не было.
Если это не исключение, но просто установка указателя ошибки в myerrorlist
, это более сложная проблема. Я не вижу ничего, что документы, которые показывают, как легко понять это, но я бы посмотрел на эти возможности.
- Вы можете вызвать функции WSA (например,
WSAGetLastError()
), чтобы понять это. Я не уверен, насколько это просто с C#. Вы можете попробовать accept()
ошибочный сокет и посмотреть, дает ли это вам какое-либо исключение, детализирующее, почему это проблема.
- Класс
Socket
имеет член Handle
, который является ручкой операционной системы для гнезда. После этого можно извлечь информацию об ошибке.
- Вы думали об использовании потоков для обработки соединений и обход всего
select()
(т. Е. Используя только accept()
, но из нескольких потоков)?
Другое, что я нашел, связано с отладкой сокетов. This page имеет раздел внизу, который показывает, как выполнять трассировку сети. .NET 2, по-видимому, не поддерживал это для select()
, но это, возможно, изменилось в последней версии.
Спасибо за ваш ответ. К сожалению, SocketException никогда не выбрасывается. Select() сигнализирует об ошибке, сохраняя сокет в myerrorlist, а не удаляя его. Я отредактирую вопрос, чтобы учесть отсутствующий 4-й аргумент. Я использую 0 в своем коде. –