Мне интересно, есть ли способ опроса сокета в C#, когда выполняется только одно из условий (данные доступны для чтения), я знаю о сокет .Poll, но это может возвращать true если задано любое число из трех условий, указанных здесь: MSDN: Socket.PollЕсть ли способ опросить сокет в C# только тогда, когда что-то доступно для чтения?
ответ
Согласно документации MSDN есть три причины, которые возвращают верно для
Poll(microSeconds, SelectMode.SelectRead);
- если
Listen()
была вызвана и соединение находится на рассмотрении - Если данные доступны для чтения
- Если соединение было закрыто, сброшено или завершено
Давайте посмотрим, если мы можем различать их:
- Вы всегда знаете, если
Listen()
был назван раньше, так что вам не нужно считать, что причина, если у вас нет. - Хорошо, вы идете на это.
- Означает, что вы не можете оставаться в вызове Poll() и должны выяснить, что на самом деле произошло. Один из вариантов - проверить состояние сокета сразу после возврата
Poll()
.
Вывод:
нужно не считать
и 3.может быть обработано путем проверки состояния сокета при каждом возврате истины.
Так что я пошел бы на (непроверенные):
if (s.Poll(microSeconds, SelectMode.SelectRead)))
{
if (!s.Connected)
// Something bad has happened, shut down
else
// There is data waiting to be read"
}
Найденное что-то в своем классе NetworkStream. Свойство NetworkStream.DataAvailable возвращает true, если данные доступны для чтения. Возвращается объект сетевого потока, связанный с TcpListener и TcpClient. Это уровень абстракции выше, чем сокет.
Я не нашел возможности подключиться от Socket к NetworkStream. NetworkStream использует сокет и представляет собой представление потока сокета. Но я не знаю, что делает сетевой поток с сокетом.
Вы можете использовать системный вызов select() для базового дескриптора.
Моя первая мысль тоже, но не shure, если это то, что означает «темная звезда». – Christian13467
true, если прослушивание прослушивается и соединение находится на рассмотрении; -или- true, если данные доступны для чтения; -или- true, если соединение было закрыто, сброшено или завершено; в противном случае возвращает false.
Я понимаю, что вы хотите проверить, является ли второй вариант истинным? После проверки правильности ответа опроса вы можете проверить, открыто ли соединение, что означает; не соединение, закрытие, сброс или завершение.
Если он открыт, то это второй вариант, возвращающий true.
like: if (m_sock.Poll (-1, SelectMode.SelectRead) && (m_sock.Connected == true))? –
Я бы предположил, что да. – Phoexo
Вы можете использовать свойство Socket Available. Он возвращает количество доступных данных для чтения.
Вы можете использовать Select() метод вместо Poll(). Фактически при просмотре Socket.Poll с ILSpy (инструментом отражателя) внутренний код вызывает выбор в сокете.
Кроме того, вызов Poll() в замкнутом цикле увеличит распределение памяти, так как при каждом вызове новый IntPtr []. Вызов Select() позволяет повторно использовать массивы вместо выделения новых под капотом.
Спасибо всем за ваш ответ. –
Вы должны проверить Подключен перед вызовом опроса или опроса для записи сначала перед чтением, так как это всегда связано с подключением под капотом. – Jay