2

我对python和网络编程的了解不多。目前我正在尝试实现一个简单的应用程序,它可以接收用户发送的短信,从谷歌搜索 api 获取一些信息,并通过短信将结果返回给用户。此应用程序将继续收听用户的消息并立即回复。

如何获取用户发送的短信?这是来自中国移动供应商的名为飞信的程序。客户端飞信,就像一个即时通讯工具,可以发送/接收消息给其他使用手机接收/发送短信的人。

我正在使用一个模拟飞信程序的开源python程序。所以基本上我可以使用这个 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')

python代码中的第150行如下:

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不是很熟悉,尤其是socket部分,而且对Jython的使用也很陌生,我真的需要你的帮助或者只是建议或解释。

非常感谢!

4

2 回答 2

2

如 jython 选择文档页面所述,只有非阻塞模式的套接字可以在 jython 上进行多路复用,而 cpython 中的套接字可以是阻塞的也可以是非阻塞的。

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

这是 Java 的一个限制,jython 无能为力。

jython 选择模块中有一个针对这种确切情况的特殊函数,即 cpython_compatible_select 函数。

您没有在上面的代码中显示选择模块的导入,但根据我所看到的,您必须进行这样的导入

从选择导入选择

如果你用这个替换那个导入

从选择导入 cpython_compatible_select 作为选择

然后一切都应该正常工作。

最后,请务必阅读选择模块文档页面上的“警告”部分。

于 2010-04-01T15:23:57.513 回答
1

该错误表明您已尝试调用select设置为(默认情况下)阻止等待输入的套接字。使其成为非阻塞的可移植方法是找到self.__sock创建位置并在其上调用socket.setblocking(0)

原则上,您可以setblockingrecvselect 调用之前调用,但这会让读者感到困惑。由于这些是对低级套接字例程的直接调用,因此这不是严格意义上的 Python 问题,而是关于适合您平台的套接字系统调用操作的问题。

于 2010-03-28T13:44:05.437 回答