2017-04-09 455 views
0

我以前做的项目与标准输入子管材连接一个遥远的VIM(我的服务器上),我的客户,通过标准输出SSL套接字。我使用Python 3.4。 我的套接字(代码中的cSock)是SSL封装的,每次我尝试打开Vim时我都有同样的错误。在这里我的代码:的Python 3.4 ssl.SSLEOFError:EOF发生违反协议(_ssl.c:1638)

vimProc = sp.Popen(["rvim", file], bufsize=0, stdin=sp.PIPE, stdout=sp.PIPE) 

cSock.settimeout(1) 

rec = Reception(cSock, vimProc) 
emi = Emission(cSock, vimProc) 

rec.start() 
emi.start() 

rec.join() 
emi.join() 

在这里,我接待的线程和排放

class Reception(threading.Thread): 

def __init__(self, sock, proc): 
    threading.Thread.__init__(self) 
    self.sock = sock 
    self.proc = proc 

def run(self): 
    while self.proc.poll() == None: 
     try: 
      self.proc.communicate(self.sock.recv(1)) 
     except socket.timeout: 
      pass 


class Emission(threading.Thread): 

def __init__(self, sock, proc): 
    threading.Thread.__init__(self) 
    self.sock = sock 
    self.proc = proc 

def run(self): 
    while self.proc.poll() == None: 
     try: 
      outs = self.proc.stdout.read(1) 
      if outs == "": 
       print("EOF reached") 
      else: 
       self.sock.send(outs) 

     except socket.timeout: 
      pass 

这里回溯:

Exception in thread Thread-2: 
Traceback (most recent call last): 
    File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner 
    self.run() 
    File ".../server/edition.py", line 62, in run 
    self.sock.send(outs) 
    File "/usr/lib/python3.4/ssl.py", line 678, in send 
    v = self._sslobj.write(data) 
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:1638) 

任何解决方案?

回答

0

SSL/TLS是在TCP之上的层。但是,虽然TCP在内核中完成,但SSL/TLS在用户空间中完成。有因为这两个问题:

的第一个问题是,用户空间,从而做叉内subprocess.Popen当SSL状态被复制。但是,父对象或子对象中的此套接字上的任何操作都不会与其他进程中的状态同步,因此,如果两个进程都主动处理套接字(包括关闭它),则会导致SSL状态失败,从而导致连接错误。

即使只有子进程处理该问题,fork之后的exec(如subprocess.Popen中所做的)将仅使进程可用的内核文件描述符(在您的案例中为rvim),而不是用户空间SSL层,因为这个用户空间只在Python进程中。这样子进程将使用普通的TCP套接字进行通信,而服务器期望SSL。这也会导致连接错误并最终导致连接关闭。另见Python3 CGI HTTPS server fails on Unix

我能想到的唯一的办法是只保留SSL套接字父和使用单独的管道(或socketpair)与子进程进行通信。从父级服务器接收的所有数据(使用SSL)应该明确地转发到子进程,并且应该使用SSL将子进程中的所有数据发送到父级内的服务器。

0

感谢您的答复! 我现在使用socketpair()就像你向我解释的那样,它好多了!我可以使用我的远程vim进行无版本编辑。但只要我想退出:wq或:x我有同样的错误。但是,如果我使用:w AND AFTER:q。

Traceback (most recent call last): 
    File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner 
    self.run() 
    File ".../appcm/release/src/server/edition.py", line 73, in run 
    self.sock.send(outs) 
    File "/usr/lib/python3.4/ssl.py", line 678, in send 
    v = self._sslobj.write(data) 
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:1638) 

我可以忽略它,因为我的服务器继续没有错误,但它不是很“干净”。你知道为什么当我退出Vim时,为什么会出现这个错误:x或:wq?如果我这样做,也是没有问题的:w和之后:q。

+0

嗯,我发现这个问题。 'if buf ==“”:'没有看到EOF字符,但是“如果buf:'工作得很好。 非常感谢您的帮助@Steffen Ullrich! – Xysto

相关问题