龙空技术网

在Python中创建代理Web服务器

少儿编程Prog61 110

前言:

今天小伙伴们对“python代理服务器”可能比较重视,看官们都想要学习一些“python代理服务器”的相关知识。那么小编在网摘上汇集了一些有关“python代理服务器””的相关资讯,希望同学们能喜欢,同学们快快来了解一下吧!

与c相比,python中的套接字编程(Socket)非常用户友好。程序员不必担心有关套接字的详细信息。在python中,用户有更多机会专注于应用程序层而不是网络层。在本教程中,我们将开发一个能够处理HTTP流量的简单多线程代理服务器。它将主要基于基本的套接字编程思想。

这是代理服务器的简单实现。在接下来的教程中,我们将逐步将其开发为一个非常有用的服务器。

首先,我们将通过3个简单的步骤来完成该过程

1. 创建一个传入套接字(socket)

我们在服务器类的__init__方法中创建一个套接字serverSocket。这将为传入的连接创建一个套接字。然后,我们绑定套接字,然后等待客户端连接。

def __init__(self, config):    # Shutdown on Ctrl+C    signal.signal(signal.SIGINT, self.shutdown)     # Create a TCP socket    self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    # Re-use the socket    self.serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)    # bind the socket to a public host, and a port       self.serverSocket.bind((config['HOST_NAME'], config['BIND_PORT']))        self.serverSocket.listen(10) # become a server socket    self.__clients = {}

2. 接受客户端连接和处理

这是所有步骤中最简单但最重要的步骤。 我们等待客户的连接请求,一旦建立成功连接,我们就将请求分派到一个单独的线程中,使自己可用于下一个请求。 这使我们可以同时处理多个请求,从而将服务器的性能提高了数倍。

while True:    # Establish the connection    (clientSocket, client_address) = self.serverSocket.accept()         d = threading.Thread(name=self._getClientName(client_address),     target = self.proxy_thread, args=(clientSocket, client_address))    d.setDaemon(True)    d.start()

3. 重定向流量

代理服务器的主要功能是充当源和目标之间的中介。在这里,我们将从源中获取数据,然后将其传递给客户端。

1)首先,我们从接收到的请求数据中提取URL。

# get the request from browserrequest = conn.recv(config['MAX_REQUEST_LEN']) # parse the first linefirst_line = request.split('\n')[0]# get urlurl = first_line.split(' ')[1]

2)然后,我们找到请求的目标地址。地址是(destination_ip_address,destination_port_no)的元组。我们将从该地址接收数据。

http_pos = url.find("://") # find pos of ://if (http_pos==-1):    temp = urlelse:    temp = url[(http_pos+3):] # get the rest of urlport_pos = temp.find(":") # find the port pos (if any)# find end of web serverwebserver_pos = temp.find("/")if webserver_pos == -1:    webserver_pos = len(temp)webserver = ""port = -1if (port_pos==-1 or webserver_pos < port_pos):     # default port     port = 80     webserver = temp[:webserver_pos] else: # specific port     port = int((temp[(port_pos+1):])[:webserver_pos-port_pos-1])    webserver = temp[:port_pos] 

3)现在,我们设置到目标服务器(或远程服务器)的新连接,然后将原始请求的副本发送到服务器。然后,服务器将用一个响应来响应。所有响应消息都使用RFC 822的通用消息格式。

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(config['CONNECTION_TIMEOUT'])s.connect((webserver, port))s.sendall(request)

4)然后,我们将服务器的响应重定向到客户端。conn是与客户端的原始连接。 该响应可能大于我们在一个调用中收到的MAX_REQUEST_LEN,因此,空响应表示响应结束。

while 1:    # receive data from web server    data = s.recv(config['MAX_REQUEST_LEN'])    if (len(data) > 0):        conn.send(data) # send to browser/client    else:        break

然后,我们适当地关闭服务器连接并进行错误处理,以确保服务器按预期工作。

如何测试服务器?

1. 在终端上运行服务器。 使其保持运行并切换到您喜欢的浏览器。

2. 转到浏览器的代理设置,然后将代理服务器更改为“ localhost”,并将端口更改为“12345”。

3. 现在打开任何HTTP网站(非HTTPS),您应该能够访问浏览器上的内容。

服务器运行后,我们可以监视到客户端的请求。我们可以使用这些数据来监视正在运行的内容,也可以基于该内容开发统计信息。

我们甚至可以限制对网站的访问或将IP地址列入黑名单。在接下来的教程中,我们将在代理服务器中添加以下功能。

1. 添加域名黑名单

比如google.com,facebook.com。在我们的配置指令中创建一个黑名单域列表。现在,只需忽略/删除收到的黑名单域请求。(理想情况下,我们必须以禁止的回应来回应。)

# Check if the host:port is blacklistedfor i in range(0, len(config['BLACKLIST_DOMAINS'])):    if config['BLACKLIST_DOMAINS'][i] in url:        conn.close()return

2. 添加主机阻止

假设您可能需要允许来自特定子网的连接或特定人的连接。要添加此内容,请创建所有允许的主机的列表。由于主机也可以是子网,因此添加正则表达式以匹配IP地址,尤其是IPV4地址。“ IPv4地址以点十进制表示法规范表示,该点由四个十进制数字组成,每个数字的范围从0到255,由点分隔,例如172.16.254.1。每个部分代表一组8位(八位字节)的地址。”

标签: #python代理服务器