2013-04-22 68 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 
>>> 
相关问题