2009-08-08 6 views
3

Мне интересно, есть ли способ опроса сокета в C#, когда выполняется только одно из условий (данные доступны для чтения), я знаю о сокет .Poll, но это может возвращать true если задано любое число из трех условий, указанных здесь: MSDN: Socket.PollЕсть ли способ опросить сокет в C# только тогда, когда что-то доступно для чтения?

ответ

5

Согласно документации MSDN есть три причины, которые возвращают верно для

Poll(microSeconds, SelectMode.SelectRead);

  1. если Listen() была вызвана и соединение находится на рассмотрении
  2. Если данные доступны для чтения
  3. Если соединение было закрыто, сброшено или завершено

Давайте посмотрим, если мы можем различать их:

  1. Вы всегда знаете, если Listen() был назван раньше, так что вам не нужно считать, что причина, если у вас нет.
  2. Хорошо, вы идете на это.
  3. Означает, что вы не можете оставаться в вызове Poll() и должны выяснить, что на самом деле произошло. Один из вариантов - проверить состояние сокета сразу после возврата Poll().

Вывод:

  1. нужно не считать

  2. и 3.может быть обработано путем проверки состояния сокета при каждом возврате истины.

Так что я пошел бы на (непроверенные):

if (s.Poll(microSeconds, SelectMode.SelectRead))) 
{ 
    if (!s.Connected) 
    // Something bad has happened, shut down 
    else 
    // There is data waiting to be read" 
} 
+0

Спасибо всем за ваш ответ. –

+0

Вы должны проверить Подключен перед вызовом опроса или опроса для записи сначала перед чтением, так как это всегда связано с подключением под капотом. – Jay

1

Найденное что-то в своем классе NetworkStream. Свойство NetworkStream.DataAvailable возвращает true, если данные доступны для чтения. Возвращается объект сетевого потока, связанный с TcpListener и TcpClient. Это уровень абстракции выше, чем сокет.

Я не нашел возможности подключиться от Socket к NetworkStream. NetworkStream использует сокет и представляет собой представление потока сокета. Но я не знаю, что делает сетевой поток с сокетом.

1

Вы можете использовать системный вызов select() для базового дескриптора.

+1

Моя первая мысль тоже, но не shure, если это то, что означает «темная звезда». – Christian13467

0

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

Я понимаю, что вы хотите проверить, является ли второй вариант истинным? После проверки правильности ответа опроса вы можете проверить, открыто ли соединение, что означает; не соединение, закрытие, сброс или завершение.

Если он открыт, то это второй вариант, возвращающий true.

+0

like: if (m_sock.Poll (-1, SelectMode.SelectRead) && (m_sock.Connected == true))? –

+0

Я бы предположил, что да. – Phoexo

4

Вы можете использовать свойство Socket Available. Он возвращает количество доступных данных для чтения.

1

Вы можете использовать Select() метод вместо Poll(). Фактически при просмотре Socket.Poll с ILSpy (инструментом отражателя) внутренний код вызывает выбор в сокете.

Кроме того, вызов Poll() в замкнутом цикле увеличит распределение памяти, так как при каждом вызове новый IntPtr []. Вызов Select() позволяет повторно использовать массивы вместо выделения новых под капотом.