python实现端口转发器的方法

 更新时间:2015年03月13日 15:19:06   作者:chongq  
这篇文章主要介绍了python实现端口转发器的方法,涉及Python实现端口转发的技巧,支持TCP和UDP协议,需要的朋友可以参考下

本文实例讲述了python实现端口转发器的方法。分享给大家供大家参考。具体如下:

下面的python代码实现端口转发器,支持udp端口转发

由于工作需要用到一个端口转发器,并且要求支持TCP和UDP协议。在网上找了蛮久,但没有中意的。于是就自己写了一个。这个转发器是基于python cookbook的一个示例改写的,原先的这个示例只支持TCP协议,我这里增加了UDP协议的支持,程序写的不怎么好,不过它确实能用!

portmap.py代码如下:

复制代码 代码如下:
#-* -coding: UTF-8 -* -
'''
Created on 2012-5-8
@author: qh
'''
import time,socket,threading
def log(strLog):
    strs=time.strftime("%Y-%m-%d %H:%M:%S")
    print strs+"->"+strLog
class pipethread(threading.Thread):
    '''
    classdocs
    '''
    def __init__(self,source,sink):
        '''
        Constructor
        '''
        threading.Thread.__init__(self)
        self.source=source
        self.sink=sink
        log("New Pipe create:%s->%s" % (self.source.getpeername(),self.sink.getpeername()))
    def run(self):
        while True:
            try:
                data=self.source.recv(1024)
                if not data: break
                self.sink.send(data)
            except Exception ,ex:
                log("redirect error:"+str(ex))
                break
        self.source.close()
        self.sink.close()
class portmap(threading.Thread):
    def __init__(self,port,newhost,newport,local_ip=''):
        threading.Thread.__init__(self)
        self.newhost=newhost
        self.newport=newport
        self.port=port
        self.local_ip=local_ip
        self.sock=None
        self.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.sock.bind((self.local_ip,port))
        self.sock.listen(5)
        log("start listen protocol:%s,port:%d " % ('tcp',port))
    def run(self):
        while True:
            fwd=None
            newsock=None
            newsock,address=self.sock.accept()
            log("new connection->protocol:%s,local port:%d,remote address:%s" % ('tcp',self.port,address[0]))
            fwd=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            try:
                fwd.connect((self.newhost,self.newport))
            except Exception ,ex:
                log("connet newhost error:"+str(ex))
                break
            p1=pipethread(newsock,fwd,self.protocol)
            p1.start()
            p2=pipethread(fwd,newsock,self.protocol)
            p2.start()
class pipethreadUDP(threading.Thread):
    def __init__(self,connection,connectionTable,table_lock):
        threading.Thread.__init__(self)
        self.connection=connection
        self.connectionTable=connectionTable
        self.table_lock=table_lock
        log('new thread for new connction')
    def run(self):
        while True:
            try:
                data,addr=self.connection['socket'].recvfrom(4096)
                #log('recv from addr"%s' % str(addr))
            except Exception ,ex:
                log("recvfrom error:"+str(ex))
                break
            try:
                self.connection['lock'].acquire()
                self.connection['Serversocket'].sendto(data,self.connection['address'])
                #log('sendto address:%s' % str(self.connection['address']))
            except Exception ,ex:
                log("sendto error:"+str(ex))
                break
            finally:self.connection['lock'].release()
            self.connection['time']=time.time()
        self.connection['socket'].close()
        log("thread exit for: %s" % str(self.connection['address']))
        self.table_lock.acquire()
        self.connectionTable.pop(self.connection['address'])
        self.table_lock.release()
        log('Release udp connection for timeout:%s' % str(self.connection['address']))
class portmapUDP(threading.Thread):
    def __init__(self,port,newhost,newport,local_ip=''):
        threading.Thread.__init__(self)
        self.newhost=newhost
        self.newport=newport
        self.port=port
        self.local_ip=local_ip
        self.sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        self.sock.bind((self.local_ip,port))
        self.connetcTable={}
        self.port_lock=threading.Lock()
        self.table_lock=threading.Lock()
        self.timeout=300
        #ScanUDP(self.connetcTable,self.table_lock).start()
        log('udp port redirect run->local_ip:%s,local_port:%d,remote_ip:%s,remote_port:%d' % (local_ip,port,newhost,newport))
    def run(self):
        while True:
            data,addr=self.sock.recvfrom(4096)
            connection=None
            newsock=None
            self.table_lock.acquire()
            connection=self.connetcTable.get(addr)
            newconn=False
            if connection is None:
                connection={}
                connection['address']=addr
                newsock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
                newsock.settimeout(self.timeout)
                connection['socket']=newsock
                connection['lock']=self.port_lock
                connection['Serversocket']=self.sock
                connection['time']=time.time()
                newconn=True
                log('new connection:%s' % str(addr))
            self.table_lock.release()
            try:
                connection['socket'].sendto(data,(self.newhost,self.newport))
            except Exception ,ex:
                log("sendto error:"+str(ex))
                #break
            if newconn:
                self.connetcTable[addr]=connection
                t1=pipethreadUDP(connection,self.connetcTable,self.table_lock)
                t1.start()
        log('main thread exit')
        for key in self.connetcTable.keys():
            self.connetcTable[key]['socket'].close()
if __name__=='__main__':
    myp=portmapUDP(10061,'10.0.1.29',161)
    myp.start()
    #myp.__stop()

希望本文所述对大家的Python程序设计有所帮助。

相关文章

  • OpenCV+Imutils实现图像的旋转操作

    OpenCV+Imutils实现图像的旋转操作

    imutils是在OPenCV基础上的一个封装,达到更为简结的调用OPenCV接口的目的,它可以轻松的实现图像的平移,旋转,缩放,骨架化等一系列的操作。本文将用其实现图像的旋转操作,感兴趣的可以学习一下
    2022-05-05
  • PyCharm无法登陆Codeium的解决方法

    PyCharm无法登陆Codeium的解决方法

    Codeium插件可以自动建议、解释代码、生成注释和根据注释生成代码等,本文主要介绍了PyCharm无法登陆Codeium的解决方法,感兴趣的可以了解一下
    2023-11-11
  • neo4j网址拒绝访问的问题及解决

    neo4j网址拒绝访问的问题及解决

    这篇文章主要介绍了neo4j网址拒绝访问的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • 正则表达式在Python中的应用小结

    正则表达式在Python中的应用小结

    正则表达式是一种强大的文本模式匹配工具,它可以帮助我们快速地检索、替换或提取字符串中的特定模式,在本文中,我将通过一些示例代码,详细介绍正则表达式在Python中的应用,感兴趣的朋友一起看看吧
    2024-07-07
  • Python增强下git那长长的指令详解

    Python增强下git那长长的指令详解

    这篇文章主要介绍了Python增强下git那长长的指令 ,在开发中用到的代码目录结构,本文也给大家详细讲解,需要的朋友可以参考下
    2021-09-09
  • python使用ctypes调用第三方库时出现undefined symbol错误详解

    python使用ctypes调用第三方库时出现undefined symbol错误详解

    python中时间的库有time和datetime,pandas也有提供相应的时间处理函数,下面这篇文章主要给大家介绍了关于python使用ctypes调用第三方库时出现undefined symbol错误的相关资料,需要的朋友可以参考下
    2023-02-02
  • Python pyecharts绘制柱状图

    Python pyecharts绘制柱状图

    这篇文章主要介绍了Python pyecharts绘制柱状图,文章介绍的柱状/条形图,通过柱形的高度/条形的宽度来表现数据的大小,感兴趣的小伙伴一起进入文章学习更详细内容吧
    2021-12-12
  • Python中Django 后台自定义表单控件

    Python中Django 后台自定义表单控件

    本篇文章主要介绍了Python中Django 后台自定义表单控件,其实 django 已经为我们提供了一些可用的表单控件,比如:多选框、单选按钮等,有兴趣的开业了解一下。
    2017-03-03
  • Python批量加密Excel文件的实现示例

    Python批量加密Excel文件的实现示例

    在日常工作中,保护敏感数据是至关重要的,本文主要介绍了Python批量加密Excel文件的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • 通过实例解析Python return运行原理

    通过实例解析Python return运行原理

    这篇文章主要介绍了通过实例解析Python return运行原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03

最新评论