网络端口的转发和重定向(Python)

简介:

【任务】

    需要将某个网络端口转发到另一个主机(forwarding),但可能会是不同的端口(redirecting)。

【解决方案】

    两个使用threading和socket模块的类就能完成我们需要的端口转发和重定向。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#encoding=utf8
#author: walker摘自《Python Cookbook(2rd)》
#date: 2015-06-11
#function: 网络端口的转发和重定向(适用于python2/python3)
 
import  sys, socket, time, threading
 
LOGGING  =  True
loglock  =  threading.Lock()
 
#打印日志到标准输出
def  log(s,  * a):
     if  LOGGING:
         loglock.acquire()
         try :
             print ( '%s:%s'  %  (time.ctime(), (s  %  a)))
             sys.stdout.flush()
         finally :
             loglock.release()
             
class  PipeThread(threading.Thread):
     pipes  =  []       #静态成员变量,存储通讯的线程编号
     pipeslock  =  threading.Lock()
     def  __init__( self , source, sink):
         #Thread.__init__(self)  #python2.2之前版本适用
         super (PipeThread,  self ).__init__()
         self .source  =  source
         self .sink  =  sink
         log( 'Creating new pipe thread %s (%s -> %s)'
                 self , source.getpeername(), sink.getpeername())
         self .pipeslock.acquire()
         try :
             self .pipes.append( self )
         finally :
             self .pipeslock.release()
         self .pipeslock.acquire()
         try :
             pipes_now  =  len ( self .pipes)
         finally :
             self .pipeslock.release()
         log( '%s pipes now active' , pipes_now)
     def  run( self ):
         while  True :
             try :
                 data  =  self .source.recv( 1024 )
                 if  not  data:
                     break
                 self .sink.send(data)
             except :
                 break
         log( '%s terminating' self )       
         self .pipeslock.acquire()
         try :
             self .pipes.remove( self )
         finally :
             self .pipeslock.release()
         self .pipeslock.acquire()
         try :
             pipes_left  =  len ( self .pipes)
         finally :
             self .pipeslock.release()
         log( '%s pipes still active' , pipes_left)
         
class  Pinhole(threading.Thread):
     def  __init__( self , port, newhost, newport):
         #Thread.__init__(self)  #python2.2之前版本适用
         super (Pinhole,  self ).__init__()
         log( 'Redirecting: localhost: %s->%s:%s' , port, newhost, newport)
         self .newhost  =  newhost
         self .newport  =  newport
         self .sock  =  socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         self .sock.bind(('', port))
         self .sock.listen( 5 )      #参数为timeout,单位为秒
     def  run( self ):
         while  True :
             newsock, address  =  self .sock.accept()
             log( 'Creating new session for %s:%s' * address)
             fwd  =  socket.socket(socket.AF_INET, socket.SOCK_STREAM)
             fwd.connect(( self .newhost,  self .newport))
             PipeThread(newsock, fwd).start()     #正向传送
             PipeThread(fwd, newsock).start()     #逆向传送
             
if  __name__  = =  '__main__' :
     print ( 'Starting Pinhole port fowarder/redirector' )
     
     try :
         port  =  int (sys.argv[ 1 ])
         newhost  =  sys.argv[ 2 ]
         try :
             newport  =  int (sys.argv[ 3 ])
         except  IndexError:
             newport  =  port
     except  (ValueError, IndexError):
         print ( 'Usage: %s port newhost [newport]'  %  sys.argv[ 0 ])
         sys.exit( 1 )
         
     #sys.stdout = open('pinhole.log', 'w')      #将日志写入文件
     Pinhole(port, newhost, newport).start()

【讨论】

    当你在管理一个网络时,即使是一个很小的网络,端口转发和重定向的功能有时也能给你很大的帮助。一些不在你的控制之下的应用或者服务可能是以硬连接的方式接入到某个特定的服务器的地址或端口。通过插入转发和重定向,你就能将对应用的连接请求发送到其他更合适的主机或端口上。

            

摘自《Python Cookbook(第2版)中文版》


相关阅读:端口转发(Linux/Windows)


*** walker ***

本文转自walker snapshot博客51CTO博客,原文链接http://blog.51cto.com/walkerqt/1660749如需转载请自行联系原作者


RQSLT

相关文章
|
13天前
|
数据采集 存储 API
网络爬虫与数据采集:使用Python自动化获取网页数据
【4月更文挑战第12天】本文介绍了Python网络爬虫的基础知识,包括网络爬虫概念(请求网页、解析、存储数据和处理异常)和Python常用的爬虫库requests(发送HTTP请求)与BeautifulSoup(解析HTML)。通过基本流程示例展示了如何导入库、发送请求、解析网页、提取数据、存储数据及处理异常。还提到了Python爬虫的实际应用,如获取新闻数据和商品信息。
|
14天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
14天前
|
程序员 开发者 Python
Python网络编程基础(Socket编程) 错误处理和异常处理的最佳实践
【4月更文挑战第11天】在网络编程中,错误处理和异常管理不仅是为了程序的健壮性,也是为了提供清晰的用户反馈以及优雅的故障恢复。在前面的章节中,我们讨论了如何使用`try-except`语句来处理网络错误。现在,我们将深入探讨错误处理和异常处理的最佳实践。
|
2天前
|
机器学习/深度学习 算法 算法框架/工具
数据分享|PYTHON用KERAS的LSTM神经网络进行时间序列预测天然气价格例子
数据分享|PYTHON用KERAS的LSTM神经网络进行时间序列预测天然气价格例子
23 0
|
1天前
|
存储 网络协议 关系型数据库
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
|
2天前
|
机器学习/深度学习 算法 Python
Python用RNN神经网络:LSTM、GRU、回归和ARIMA对COVID19新冠疫情人数时间序列预测
Python用RNN神经网络:LSTM、GRU、回归和ARIMA对COVID19新冠疫情人数时间序列预测
47 12
|
7天前
|
机器学习/深度学习 Python
Python用LSTM长短期记忆神经网络对不稳定降雨量时间序列进行预测分析
Python用LSTM长短期记忆神经网络对不稳定降雨量时间序列进行预测分析
19 0
|
7天前
|
JSON 网络协议 API
Python网络编程面试题精讲
【4月更文挑战第15天】本文介绍了Python网络编程的面试重点,包括基础Socket编程、HTTP协议与requests库、异步编程与asyncio库。通过实例解析常见面试题,强调了非阻塞套接字、异常处理、HTTP状态码检查以及异步任务管理等关键点。提供代码示例帮助读者巩固概念,助力面试准备。
15 0
|
9天前
|
机器学习/深度学习 存储 测试技术
使用PYTHON中KERAS的LSTM递归神经网络进行时间序列预测
使用PYTHON中KERAS的LSTM递归神经网络进行时间序列预测
19 0
|
10天前
|
机器学习/深度学习 资源调度 数据可视化
使用Python和Keras进行主成分分析、神经网络构建图像重建
使用Python和Keras进行主成分分析、神经网络构建图像重建
13 1