回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我想用python创建一个vpn服务器,我找到了这个解决方案:<a href="http://voorloopnul.com/blog/a-python-proxy-in-less-than-100-lines-of-code/" rel="nofollow noreferrer">http://voorloopnul.com/blog/a-python-proxy-in-less-than-100-lines-of-code/</a></p>
<p>但是,它在<code>Python 2</code>上工作,我使用<code>python 3</code>。因此,我重写了一些代码,结果如下:</p>
<pre><code>import socket
from select import select
import sys
import logging
from this import s
class TcpTee:
def __init__(self, source_port, destination):
self.destination = destination
self.teesock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.teesock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.teesock.bind(('127.0.0.1', source_port))
self.teesock.listen(200)
# Linked client/server sockets in both directions
self.channel = {}
def run(self):
while 1:
inputready, outputready, exceptready = select([self.teesock] + self.channel.keys(), [], [])
for s in inputready:
if s == self.teesock:
self.on_accept()
break
data = s.recv(4096)
if not data:
self.on_close(s)
break
self.on_recv(s, data)
def on_accept(self):
clientsock, clientaddr = self.teesock.accept()
serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
serversock.connect(self.destination)
except Exception:
logging.exception(
'Could not connect to server %s. Closing connection to client %s' % (self.destination, clientaddr))
clientsock.close()
else:
logging.info("%r has connected", clientaddr)
self.channel[clientsock] = serversock
self.channel[serversock] = clientsock
def on_close(self, sock):
logging.info("%s has disconnected", s.getpeername())
othersock = self.channel[sock]
sock.close()
othersock.close()
del self.channel[sock]
del self.channel[othersock]
def on_recv(self, sock, data):
print(data)
self.channel[sock].send(data)
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("listen_port", help="The port this process will listen on.", type=int)
parser.add_argument("server_host", help="The remote host to connect to.")
parser.add_argument("server_port", help="The remote port to connect to.", type=int)
args = parser.parse_args()
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
tee = TcpTee(int(args.listen_port), (args.server_host, int(args.server_port)))
try:
tee.run()
except KeyboardInterrupt:
logging.info("Ctrl C - Good Bye")
sys.exit(1)
</code></pre>
<p>最初,启动时没有发生任何事情,但在进行小的编辑后,启动时出现了一个错误:</p>
<pre><code>The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
usage: vpn.py [-h] listen_port server_host server_port
vpn.py: error: the following arguments are required: listen_port, server_host, server_port
Process finished with exit code 2
</code></pre>
<p>从来没有面对过这样的问题,怎么能纠正呢?或者可能有人已经有了这个实现</p>