2009-02-16 3 views
3

Я звоню Bind(), а затем Listen() в системном каталоге.Sockets.Socket. Ни одно из этих вызовов не вызывает исключение.Как найти причину Socket.Select() сообщать об ошибке

Позже я сделать вызов:

Socket.Select(myreadlist,mywritelist,myerrorlist,0); 

с myreadlist и myerrorlist содержащего сокет в вопросе. Выберите отчет моего сокета как имеющий ошибку, оставив сокет в errorList, вместо того, чтобы удалять его из списка. Нигде в программе исключение SocketException.

Я не могу понять, как правильно я должен спрашивать систему: «хорошо, поэтому что пошло не так?»

Кто-нибудь знает?

Спасибо, Лукас

редактировать: добавить 4-й аргумент = 0 для выбора + объяснил лучше, как выбрать() говорит мне, произошла ошибка.

ответ

1

Я не знаю 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(), но это, возможно, изменилось в последней версии.

+0

Спасибо за ваш ответ. К сожалению, SocketException никогда не выбрасывается. Select() сигнализирует об ошибке, сохраняя сокет в myerrorlist, а не удаляя его. Я отредактирую вопрос, чтобы учесть отсутствующий 4-й аргумент. Я использую 0 в своем коде. –

0

Документация для вызова Select() говорит, что это:

Если вы сделали неблокируемый вызов Connect, параметр checkerror идентифицирует сокеты, которые не связаны с успехом.

И документация для метода опроса() (который он предлагает использовать для определения состояния одного сокета) в режиме SelectError говорит:

верно, если обработка Connect, которая не блокирует , и соединение не выполнено; -или- true, если OutOfBandInline не установлен, и доступны внеполосные данные; в противном случае возвращает false.

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

+0

Вы не вызываете connect() со стороны сервера, это клиентский вызов. Q'er вызвал bind() и listen() и использует select(), чтобы определить, какие сокеты они могут принимать(). – paxdiablo

+0

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

Смежные вопросы