2010-03-28 52 views
2

我對python和網絡編程沒有太多瞭解。目前我正在嘗試實現一個簡單的應用程序,它可以接收用戶發送的文本消息,從谷歌搜索API獲取一些信息,並通過文本消息將結果返回給用戶。此應用程序將繼續偵聽用戶消息並立即回覆。關於在Python中運行接收套接字時使用jython的問題

我如何獲得用戶發送的文本短消息?這是來自中國移動供應商的一個名爲fetion的程序。客戶端功能就像即時通訊工具一樣,可以向使用移動設備接收/發送短信的其他人發送/接收消息。

我正在使用一個開源的python程序來模擬飛信程序。所以基本上我可以使用這個Python程序與通過短信使用手機的人進行通信。

我的核心程序基於java,所以我需要把這個python程序放到java環境中。我正在使用jython,現在我可以通過一些java代碼行向用戶發送消息。

但真正的問題是通過短信從用戶接收的過程。在Python代碼中,會創建一個新線程來持續監聽用戶。它應該是OK在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,尤其是套接字部分,也是Jython使用中的新東西,我真的需要你的幫助或者只是建議或解釋。

非常感謝!

回答

1

錯誤指出您已嘗試在設置的套接字上調用select(默認情況下)阻止等待輸入。使其無阻塞的便攜式方法是找到self.__sock的創建位置,並在其上調用socket.setblocking(0)

您可以在選擇呼叫之前調用原則上的setblocking,recv但它會讓讀者感到困惑。由於這些是直接調用低級套接字例程,所以這不是一個Python問題,而是一個關於適合您的平臺的系統調用的操作。

2

正如jython select documentaion頁所述,只有非阻塞模式下的套接字可以在jython上覆用,這與cpython相反,其中套接字可以是阻塞的或非阻塞的。

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

這是Java的限制,即Jython會做什麼改變。

對於這種確切情況,cpython_compatible_select函數在jython select模塊中有一個特殊功能。

你不顯示在上面的代碼中選擇模塊的進口,但基於我所看到的,你必須做這樣的

從選擇進口的進口選擇

如果更換與此

是進口從選擇進口cpython_compatible_select作爲選擇

然後一切都應該正常工作。

最後,請務必閱讀選擇模塊文檔頁面上的「警告」部分。