2009-08-24 3 views
2

Мой сервер/клиент запускает новый поток «readerThread()» для чтения входящего трафика tcp. Этот поток блокируется при чтении(). Как я могу выйти из этого readerThread().Выход из потока, блокирующего TCP-чтение, на C#

Один из способов - запустить другой поток, который закрывает сокет, когда поток должен быть выведен, чтобы считывание завершилось. есть ли более чистый/лучший способ сделать это.

ответ

1

Если вы используете команду blocking read(), вы должны почти всегда иметь еще один поток управления, который отвечает за его закрытие и очистку.

Как правило, я бы использовал вызов select(), который истекает через 1 секунду или около того, чтобы проверить, есть ли данные для чтения, и каждый цикл тайм-аута проверяет, был ли флаг состояния выключения другим потоком.

Но если вы идете с чистой блокировкой, используйте контрольную нить, как вы предлагаете.

+0

like select() с тайм-аутом в сетевом программировании unix? У вас есть какие-либо примеры его выполнения в C# – Kazoom

+0

В качестве альтернативы, просто используйте неблокирующий ввод-вывод и проверяйте статус при возврате вызова функции. –

+0

Если это простая программа, предложение Мэтью - хорошая идея. На данный момент у меня нет примеров на C#. Но да, как select(). В C# также должен быть выбран вызов. , , select не только команда unix, но и в окнах. –

-1

Другой способ сделать это, чтобы послать пакет в 0 байт в вашем сокете где-то еще в вашем собственном приложении, когда вы хотите, чтобы закрыть его.

Я нашел, что это немного более чистый подход, чем закрытие coket из другого потока, так как исключение будет вызываться прослушивающей нитью, если вы закроете на нем сокет.

+0

В TCP нет такой вещи, как 0 байтовый пакет, и вы не можете ничего отправлять в прослушивающий сокет. – EJP

0

Я несколько озадачен тем, что именно вы делаете: нет метода read() для класса Socket в .NET.

Моя рекомендация заключается в создании второго сокета, который прослушивает определенный порт, и вместо этого имеет блок потока в Socket.Select. Подключение к этому второму сокету должно выполняться как запрос на завершение работы (возможно, после надлежащей проверки подлинности, например, путем отправки пароля приложения через этот сокет).

3

Я не понял вопрос. Вот что я думаю, что вы должны делать.

  • Если вы создали сокет в родительском потоке, и использовать только новый поток для чтения входных данных, то я хотел бы предложить вызов Socket.Shutdown(). Таким образом, получающую метода вернет 0 (нет байты), и вы можете выйти из метода потока. Shutdown отключит отправку/получение, но если в буфере есть какие-либо данные, ожидающие отправки/получения, он будет гарантировать, что он будет отправлен/получен до закрытия сокета. Метод Receive вернет 0, если вы вызываете shutdown, когда сокет заблокирован в Receive, но он выдает исключение сокета с кодом ошибки Socket = Shutdown (или 10058). Поэтому будьте готовы поймать и обработать его.

  • Если создать сокет в новом потоке, и его принимать новые соединения (Socket.Listen() и Socket.Accept), то вы можете связаться с этой розеткой из родительской нити и отправить 0 байт. Вы можете выйти из нового потока, когда методы приема вернут 0 байтов.

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

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