2013-04-22 67 views
1

在嵌入python解釋器的C程序中,我通過TCP套接字產生了一個python交互式控制檯。在套接字上沒有換行python交互式控制檯

import socket 
import code 
import sys 

s = socket.socket() 
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
s.bind(('0.0.0.0', 2000)) 
s.listen(1) 
c = s.accept()[0] # client socket 

def sread(s, len): 
     return s.recv(len) 
def swrite(s, str): 
     return s.sendall(str) 
def sreadline(s): 
     return sread(s, 256) # lazy implementation for quick testing 
socket.socket.read = sread 
socket.socket.write = swrite 
socket.socket.readline = sreadline 
sys.stdin = c 
sys.stdout = c 
sys.stderr = c 
code.interact() # runs the interactive console 

這基本上工作。 但是,交互式控制檯在返回某些用戶輸入語句的結果時永遠不會發出任何行尾字符。 換句話說,我們得到的東西是這樣的:

nc localhost 2000 
Python 2.7.3 (default, Sep 26 2012, 21:53:55) 
[GCC 4.7.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
(InteractiveConsole) 
>>> 1+1 
2>>> 

我們看到的結果是後無CR-LF「2」的解釋響應用戶輸入「1 + 1」發送,並在下一個提示前'>>>'。 通過以十六進制檢查套接字用戶端的輸出,或者檢查將要寫入套接字的函數swrite中的字符串來確認是否存在任何行尾字符(CR和/或LF) ()。

現在爲什麼沒有交互式控制檯發出的行尾字符?

它可以被修復和如何?

+1

如果你可以包含足夠的代碼來重現問題,它會使答案更容易。 – Aya 2013-04-22 20:18:16

+0

當然,完成了。順便說一句,我找到了解決方法。 – user2179288 2013-04-22 20:57:21

回答

1

這與確定何時Python的應發送換行符的softspace文件屬性做,並需要寫爲了Python的正常工作。

由於您將sys.stdout設置爲「只讀」套接字對象,因此無法設置該屬性,因此您將遇到文本輸出問題。

您可以通過同樣的方式定義__getattr____setattr__方法爲你做其他的方法解決它,但它是一個完整的劈,所以你會用你的「包裝」的解決方案更好。

+0

試圖檢查這一點,我觀察到我的包裝對象在使用後出現了一個新的'softspace'屬性,它確認了你的第一個斷言(我也嘗試將此屬性自己添加到套接字,但沒有找到如何)。對於第二個斷言,我將__getattr __/__ setattr__添加到套接字類,並觀察__getattr__爲'softspace'和'encoding'調用,而__setattr__永遠不會調用,並且我無法使用__getattr __/__ setattr__解決我最初的問題,所以有什麼特別的實現__getattr __/__ setattr__套接字? – user2179288 2013-04-23 19:32:53

+0

ok ...使用getattr/setattr實際上正確執行時正確實施 – user2179288 2013-04-23 19:57:09

1

關於「爲什麼」的問題仍然存在,但至於如何解決這個問題,這裏是解決方案。 而不是添加讀/寫/ readline的方法到socket.socket類,使socket.socket類的包裝:

import socket 
import code 
import sys 

s = socket.socket() 
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
s.bind(('0.0.0.0', 2000)) 
s.listen(1) 
c = s.accept()[0] # client socket 

class sw: # socket wrapper 
    def __init__(self, s): 
     self.s = s 
    def read(self, len): 
      return self.s.recv(len) 
    def write(self, str): 
      return self.s.send(str) 
    def readline(self): 
      return self.read(256) # lazy implementation for quick testing 
c = sw(c) 
sys.stdin = c 
sys.stdout = c 
sys.stderr = c 
code.interact() # runs the interactive console 

現在這工作正常,但原因不明。

nc localhost 2000 
Python 2.7.3 (default, Sep 26 2012, 21:51:14) 
[GCC 4.7.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
(InteractiveConsole) 
>>> 1+1 
2 
>>> 
相關問題