先来说说代理,所谓代理其实跟带话差不多。比方说A要跟C通信,但A和C之间没有通信渠道,这个时候就需要有一个和AC都能通信的中间人B来中转信息。搞懂了这个之后就需要考虑如何实现这样的一个代理服务器。
代理服务器必须得响应客户端请求,因此要建立一个监听Socket来接受客户端连接请求,y由于客户端不可能只有一个(因为就算一台电脑只有1个IP但他在访问网站时都会有很多端口同时连接上服务器),所以我们的代理服务器就得为每个客户端转发他们的数据,在程序的实现上多线程技术必不可少。
下面给出伪代码
import socket import threading class ProxyServer(): def __init__(self): self.ListenSock = socket() self.ListenSock.bind() self.Clients = [] def listen_thread(self): self.ListenSock.listen() while(1): self.Clients.append(ProxyClient(self.ListenSock.accpet()) def start_work(self): start listen_thread while(1): #从内存中踢出已经断开的连接 for i in self.client: if i not alive: self.clients.remove(i)
上面伪代码中的ProxyClient就是处理每个客户端的类
class ProxyClient(): def __init__(self, Csock): self.Csock = Csock self.Rsock = None start request_process_thread def request_process_thread(self): while(1): req = self.Csock.recv() #客户端断开了 if req == '': return #从请求中获得客户端想要访问的地址 addr = get addr from req if self.Rsock == None: self.Rsock.connect(addr) #把客户端的请求转出去 self.Rscok.send(req) #开启接受web data的线程,把web data转发给客户端 start recv_web_data_thread else: #如果连接已经建立就不要再去创建新的 self.Rsock.send(req) def recv_web_data_thread(self): while(1): data = self.Rsock.recv() if data=='': return #把web data转发给客户端 self.Csock.send(data)
需要注意的是上面中的函数都需要加入try/except,不然就到处是异常退出了。另外ProxyClient中只有一个Rsock来访问web。如果是个SocketServer,那么它可以与多个客户端保持连接,但是一个Client只能连接上一个Server,Socket中的connect指定的地址也就一个。
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/8497.html