Я не знаю C #, но я знаю сокеты UNIX. Моей первой мыслью было то, что вы не вызывали accept () для сокета до выбора для чтения, но (и это доказательство того, что я знаю о сокетах меньше, чем я думал), вы можете выбрать в состоянии прослушивания, чтобы увидеть, какие сокеты могут быть приняты. Ну что ж, мы живем и учимся даже в преклонном возрасте: -)
Во всяком случае, ссылаясь на документы MSDN здесь , найденные через Google с помощью ("c #" socket bind listen select), он гласит:
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.
Похоже, что эти коды ошибок задокументированы здесь , найденные с помощью поиска Google (документация по кодам ошибок Windows Socket Version 2 API в MSDN).
Я упоминаю условия поиска Google, если MSDN перемещает их страницы. Я выводил код ошибки из пойманного исключения, а затем просматривал его в списке по второй ссылке, чтобы узнать фактическую причину сбоя. Как только мы узнаем об этом, мы сможем помочь вам в дальнейшем (или это может стать ослепительно очевидным до такой степени, что вам не нужно спрашивать нас снова: -).
Одна вещь, которая кажется неуместной: у прототипа вызова есть четвертый аргумент, число микросекунд, которые нужно ждать, если не будет активности. Ваш код в вопросе не имеет этого. Теперь, как я уже сказал, я мало знаю о C #, так что он может что-то по умолчанию (или, может быть, вы просто оставили это вопрос случайно).
Но я бы проследил за известной ошибкой, если вы используете -1 (или она по умолчанию равна -1): подробности см. здесь , но в основном это означает, что -1 возвращается немедленно, а не ждет вечно. Обходной путь - использовать -2, чтобы дать вам час или около того, но вам все равно придется учитывать тот факт, что он может вернуться, даже если не было никакой активности.
Если это не , выдающее исключение, а просто устанавливающее индикацию ошибки в myerrorlist
, это проблема хейера. Я не вижу ничего, кроме документов, показывающих, как это легко понять, но я бы посмотрел на эти возможности.
- Вы можете вызывать функции WSA (например,
WSAGetLastError()
), чтобы понять это. Я не уверен, насколько легко это из C #. Вы можете попробовать accept()
ошибочный сокет и посмотреть, дает ли это исключение, подробно описав причину проблемы.
- Класс
Socket
имеет член Handle
, который является дескриптором операционной системы для сокета. После этого можно извлечь информацию об ошибке.
- Задумывались ли вы о том, чтобы использовать потоки для обработки соединений и вообще обойти использование
select()
(т.е. использовать только accept()
, но из нескольких потоков)?
Еще одна вещь, которую я обнаружил, связана с отладкой сокетов. Эта страница имеет раздел внизу, который показывает, как выполнять трассировку сети. .NET 2, очевидно, не поддерживал это для select()
, но это могло измениться в последней версии.