This article mainly introduces how to use only 50 lines of Python code to implement a simple proxy server, and write it in the socket module using the simplest client-proxy-forward principle, for more information, see the following scenario:
I need to use the mongodb graphics client on my computer, but the mongodb server address is not open to the internet. I can only log on to host A first, and then connect to mongodb server B from host.
I originally wanted to forward through ssh port, but I do not have the permission to connect to ssh from Machine A to Machine B. So you can write one in python.
The principle is simple.
1. open a socket server to listen for connection requests
2. each time a client connection request is received, a connection request is created to the address to be forwarded. Client-> proxy-> forward. Proxy is both a socket server (listener client) and a socket client (request to forward ).
3. bind the client-> proxy and proxy-> forward sockets with a dictionary.
4. use the ing dictionary to pass the data from send/recv to intact
The code below.
# Coding = UTF-8 import socket import select import sys to_addr = ('XXX. xxx. xx. xxx', 10000) # forward address class Proxy: def _ init _ (self, addr): self. proxy = socket. socket (socket. AF_INET, socket. SOCK_STREAM) self. proxy. bind (addr) self. proxy. listen (10) self. inputs = [self. proxy] self. route = {} def serve_forever (self): print 'proxy listen... 'While 1: readable, _, _ = select. select (self. inputs, [], []) for self. sock in readable: if self. sock = self. proxy: self. on_join () else: data = self. sock. recv (8096) if not data: self. on_quit () else: self. route [self. sock]. send (data) def on_join (self): client, addr = self. proxy. accept () print addr, 'connect 'forward = socket. socket (socket. AF_INET, socket. SOCK_STREAM) forward. connect (to_addr) self. inputs + = [client, forward] self. route [client] = forward self. route [forward] = client def on_quit (self): for s in self. sock, self. route [self. sock]: self. inputs. remove (s) del self. route [s] s. close () if _ name _ = '_ main _': try: Proxy ('', 12345 )). serve_forever () # The address that the proxy server listens to cannot KeyboardInterrupt: sys. exit (1)