Вопрос об использовании jython при запуске получающего сокета в python - PullRequest
2 голосов
/ 28 марта 2010

У меня не так много знаний по питону и сетевому программированию. В настоящее время я пытаюсь реализовать простое приложение, которое может получать текстовое сообщение, отправленное пользователем, получать некоторую информацию из API поиска Google и возвращать результаты через текстовое сообщение пользователю. Это приложение будет продолжать прослушивать сообщения пользователей и немедленно отвечать.

Как получить текстовое короткое сообщение, отправленное пользователем? Это программа под названием Fetion от поставщика мобильных телефонов в Китае. Клиентское приложение, как инструмент мгновенного общения, может отправлять / получать сообщения от других людей, которые используют мобильные устройства для получения / отправки SMS.

Я использую python-программу с открытым исходным кодом, которая имитирует программу fetion. Поэтому я могу использовать эту программу на Python для общения с другими людьми, которые используют сотовый телефон с помощью SMS.

Моя основная программа основана на Java, поэтому мне нужно перенести эту программу на Python в среду Java. Я использую jython, и теперь я могу отправлять сообщения пользователям по нескольким строкам кода Java.

Но реальный вопрос - это процесс приема от пользователей через СМС. В коде Python создается новый поток для непрерывного прослушивания пользователя. В Python должно быть все в порядке, но когда я запускаю аналогичный процесс в Jython, возникает следующее исключение:

Exception in thread Thread:Traceback (most recent call last):
File "D:\jython2.5.1\Lib\threading.py", line 178, in _Thread__bootstrap
   self.run()
File "<iostream>", line 1389, in run
File "<iostream>", line 1207, in receive
File "<iostream>", line 1207, in receive
File "<iostream>", line 150, in recv
File "D:\jython2.5.1\Lib\select.py", line 223, in native_select
  pobj.register(fd, POLLIN)
File "D:\jython2.5.1\Lib\select.py", line 104, in register
  raise _map_exception(jlx)
error: (20000, 'socket must be in non-blocking mode')

Строка 150 в коде Python выглядит следующим образом:

def recv(self,timeout=False):
    if self.login_type == "HTTP":
        time.sleep(10)
        return self.get_offline_msg()
        pass
    else:
        if timeout:
            infd,outfd,errfd = select([self.__sock,],[],[],timeout)//<---line 150 here
        else:
            infd,outfd,errfd = select([self.__sock,],[],[])

        if len(infd) != 0:
            ret = self.__tcp_recv()

            num = len(ret)
            d_print(('num',),locals())
            if num == 0:
                return ret
            if num == 1:
                return ret[0]
            for r in ret:
                self.queue.put(r)
                d_print(('r',),locals())

            if not self.queue.empty():
                return self.queue.get()

        else:
            return "TimeOut"

Из-за того, что я не очень хорошо знаком с Python, особенно с частью сокетов, а также с новыми возможностями в Jython, мне действительно нужна ваша помощь или только совет или объяснение.

Большое спасибо!

Ответы [ 2 ]

2 голосов
/ 01 апреля 2010

Как указано на странице выбора документации jython, в jython мультиплексироваться могут только сокеты в неблокирующем режиме, в отличие от cpython, где сокеты могут быть либо блокирующими, либо неблокирующими.

http://wiki.python.org/jython/SelectModule#Onlysocketsinnon-blockingmodecanbemultiplexed

Это ограничение Java, при котором jython ничего не может изменить.

Для этой конкретной ситуации в модуле выбора jython есть специальная функция cpython_compatible_select.

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

из выбора импорта выберите

Если вы замените этот импорт на этот

из выбранного импорта cpython_compatible_select as select

Тогда все должно работать нормально.

Наконец, пожалуйста, прочитайте раздел «Предупреждения» на странице документации по выбранному модулю.

1 голос
/ 28 марта 2010

В сообщении об ошибке указывается, что вы пытались вызвать select в сокете, который установлен (по умолчанию) для блокировки ожидания ввода. Портативный способ сделать его неблокирующим - это найти, где создается self.__sock, и вызвать socket.setblocking (0) .

Вы можете позвонить - в принципе - setblocking в recv до вызова select, но это может смутить читателя. Поскольку это прямые вызовы низкоуровневых подпрограмм сокетов, это не вопрос Python, а вопрос о работе системного вызова socket в зависимости от вашей платформы.

...