как разблокировать заблокированный сокет? - PullRequest
0 голосов
/ 11 декабря 2010

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

Подробнее: Я подключаюсь к серверу через два сокета. Разъем 1 предназначен для общего командного взаимодействия. Сокет 2 предназначен для отмены запущенных команд. Прекращение может произойти в любое время и часто. Каждая команда, отправленная через сокет 1, получает ответ, такой как:

socket1 send: set command data
socket1 read: set command ack

Между отправкой и чтением всегда есть некоторое время, поскольку сервер ничего не отправляет обратно, пока команда не завершит выполнение.

Для прерывания выполняющихся команд я подключаюсь через другой сокет и выдаю команду прерывания. Затем я использую сокет 1 для выдачи новой команды.

Я обнаружил, что иногда команды, выдаваемые через сокет 1 после прерывания, зависают в программе. Похоже, сокет 1 заблокирован в ожидании ответа на ранее выполненную команду, которая никогда не возвращалась (и была прервана). Хотя обычно это работает, иногда нет (я не писал сервер).

В этих случаях могу ли я проверить, не заблокирован ли сокет 1 в ожидании чтения, и если да, отказаться от чтения и продолжить? Или вообще любой способ проверить, чтобы я мог закрыть эту розетку и начать заново?

ТНХ!

ОБНОВЛЕНИЕ 1: спасибо за ответы. Что касается того, почему я использую блокирующие сокеты, то это потому, что я управляю станком с ЧПУ с помощью этого кода, и мне нужно знать, когда выполнялась команда, которую я попросил выполнить. Сервер возвращает ACK, когда это сделано, так что это кажется хорошим способом справиться с этим. Мне нравится идея рефакторинга для неблокирования, но я не могу представить способ получения информации, когда команда выполняется иначе. Я посмотрю на выбор и другие варианты.

Ответы [ 4 ]

4 голосов
/ 11 декабря 2010

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

Кроме этого, единственный известный мне способ узнать, заблокирован ли сокет, это то, что ваша программа называется recv или один из ее вариантови еще не вернулся.Кто-то может знать API, которого у меня нет, но установка "заблокированного" логического значения перед вызовом recv и его очистка после этого, вероятно, лучший способ получить эту информацию.Но ты не хочешь этого делать.Поверьте мне, рефактор в конечном итоге того стоит.

2 голосов
/ 11 декабря 2010

Традиционным решением этой проблемы является использование select .Перед записью проверьте, поддерживает ли сокет запись, и, если нет, сделайте что-нибудь еще (например, сначала дождитесь ответа).На один уровень выше выбранного, Python предоставляет модуль asyncore для такой обработки.Два уровня выше, Twisted - это целая структура, занимающаяся асинхронной обработкой сообщений.

0 голосов
/ 31 марта 2011

Что вы на самом деле хотите заблокировать в select () или poll ().Единственный способ разблокировать заблокированный сокет - это получить данные или сигнал, который, вероятно, является неприемлемым.Вызов select () или poll () может блокировать ожидание одного или нескольких сокетов, либо при чтении, либо при записи (ожидание места в буфере).Они также могут занять тайм-аут, если вы хотите периодически ждать, чтобы проверить другие вещи.Взгляните на мой ответ на Block Socket с Unix и C / C ++ Help

0 голосов
/ 13 декабря 2010

Розетки должны быть полнодуплексными.Если Python блокирует запись потока в сокет, в то время как другой поток читает из того же сокета, я бы расценил это как главную ошибку в Python.Это не происходит ни на одном другом языке программирования, который я использовал.

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