zoukankan      html  css  js  c++  java
  • 利用asyncore.dispatcher写的端口转发器

    创建三个继承类,PortForwarder用于监听本地,Receiver与PortForwarder套接字相连,用于接受本地请求,发给数据给远程主机,Sender与Receiver相互包含,用于接受远程主机数据和发送数据到本地。大致形成这样的关系:本地主机---PortForwarder---Receiver---Sender---远程主机

      1 #!/usr/bin/env python
      2 #-*- coding:utf-8 -*-
      3 
      4 import argparse
      5 import asyncore
      6 import socket
      7 
      8 LOCAL_SERVER_HOST = 'localhost'
      9 REMOTE_SERVER_HOST = 'www.baidu.com'
     10 BUFSIZE = 4096
     11 LOCAL_SERVER_PORT = 0
     12 
     13 class PortForwarder(asyncore.dispatcher):#监听本地
     14     def __init__(self, ip, port, remoteip, remoteport, backlog=5):
     15         asyncore.dispatcher.__init__(self)
     16         self.remoteip = remoteip
     17         self.remoteport = remoteport
     18         self.create_socket(socket.AF_INET, socket.SOCK_STREAM)#创建一个套接字对象
     19         self.set_reuse_addr()#设置地址端口可重用
     20         self.bind((ip, port))#绑定本地ip与端口
     21         self.listen(backlog)#开始监听
     22 
     23     def handle_accept(self):#处理接受
     24         conn, addr = self.accept()#等待接受
     25         print "Connected to:", addr
     26         Sender(Receiver(conn), self.remoteip, self.remoteport)
     27 
     28 class Receiver(asyncore.dispatcher):#接受本地请求数据,发送给远程主机
     29     def __init__(self, conn):
     30         asyncore.dispatcher.__init__(self, conn)
     31         #self被初始化为该连接客户端socket
     32         #getpeername函数用于获取与某个套接字关联的外地协议地址 
     33         self.from_remote_buffer = ''#保存来自远程主机数据
     34         self.to_remote_buffer = ''    #保存本地请求数据
     35         self.sender = None
     36 
     37     def handle_connect(self):
     38         pass
     39 
     40     def handle_read(self):#接受本地请求
     41         read = self.recv(BUFSIZE)
     42         self.to_remote_buffer += read;
     43         print "receiver read", self.to_remote_buffer
     44 
     45     def writable(self):#判断是否有来自远程主机的数据,如果有,调用handle_write
     46         return (len(self.from_remote_buffer) > 0)
     47 
     48     def handle_write(self):#发送来自远程主机的数据给本地主机
     49         sent = self.send(self.from_remote_buffer)
     50         print "receiver sent", sent
     51         self.from_remote_buffer = self.from_remote_buffer[sent:]#发送完成后清空数据
     52 
     53     def handle_close(self):
     54         self.close()
     55         if self.sender:
     56             self.sender.close()
     57 
     58 class Sender(asyncore.dispatcher):#接受远程主机数据,发送本地请求数据
     59     def __init__(self, receiver, remoteaddr, remoteport):
     60         asyncore.dispatcher.__init__(self)
     61         self.receiver = receiver#建立Sender与Receiver之间联系
     62         receiver.sender = self    #建立Sender与Receiver之间联系
     63         self.create_socket(socket.AF_INET, socket.SOCK_STREAM)#创建套接字
     64         self.connect((remoteaddr, remoteport))#连接远程主机
     65 
     66     def handle_connect(self):
     67         pass
     68 
     69     def handle_read(self):#接受来自远程主机的数据
     70         read = self.recv(BUFSIZE)
     71         self.receiver.from_remote_buffer += read
     72         print "sender read", self.receiver.from_remote_buffer
     73 
     74     def writable(self):#判断是否有本地请求要发送,如果有,调用handle_write
     75         if len(self.receiver.to_remote_buffer) > 0:
     76             self.receiver.to_remote_buffer = self.receiver.to_remote_buffer.replace
     77                 (LOCAL_SERVER_HOST + ':' + str(LOCAL_SERVER_PORT), REMOTE_SERVER_HOST)
     78             #修改本地请求数据,将本地主机中host改为远程主机地址
     79         return (len(self.receiver.to_remote_buffer) > 0)
     80 
     81     def handle_write(self):#发送本地请求数据
     82         sent = self.send(self.receiver.to_remote_buffer)
     83         print "sender write",sent
     84         self.receiver.to_remote_buffer = self.receiver.to_remote_buffer[sent:]
     85 
     86     def handle_close(self):
     87         self.close()
     88         self.receiver.close()
     89 
     90 if __name__ == '__main__':
     91     parser = argparse.ArgumentParser(description="stackless socket server example")
     92     parser.add_argument('--localhost', action="store", dest="local_host", default=LOCAL_SERVER_HOST)
     93     parser.add_argument('--local-port', action="store", dest="local_port", type=int, required=True)
     94     parser.add_argument('--romote-port', action="store", dest="remote_host",default=REMOTE_SERVER_HOST)
     95     parser.add_argument('--remot-port', action="store", dest="remote_port", type=int, default=80)
     96     given_args = parser.parse_args()
     97     local_host, remote_host = given_args.local_host, given_args.remote_host
     98     local_port, remote_port = given_args.local_port, given_args.remote_port
     99     LOCAL_SERVER_PORT = local_port
    100     print "start port forwarding local %s:%s => remote %s:%s" % 
    101         (local_host, local_port, remote_host, remote_port)
    102     PortForwarder(local_host, local_port, remote_host, remote_port)
    103     asyncore.loop()
  • 相关阅读:
    关于嵌入式的技术竞争力
    CentOS7使用ISO镜像文件作为离线Yum源
    CentOS7搭建NAS文件共享存储
    CentOS7安装redis5.0.6
    Windows 10 2004及以后版本删除更新历史记录
    CentOS7手动安装MySQL 8
    python 使用lambda对dict排序
    单片机驱动-软件模拟I2C
    Linux-通过网络nfs和tftp在开发板上运行linux驱动程序
    体验一个前端视图层的mvvm的框架Knockoutjs(双向绑定,模板..)..解放您的双手,不再些那么多的dom操作..快速实现视图层数据与UI的交互处理
  • 原文地址:https://www.cnblogs.com/tindin/p/4655395.html
Copyright © 2011-2022 走看看