python实现端口转发

之前一直用花生壳做外网端口转发,但是花生壳是不稳定的噢,一次同事虚拟机用的NAT模式,虚拟机的IP地址相当于内网的内网了,内网C段是无法直接访问的,比如#有A、B、C三台计算机,A、B互通,B、C互通,但是A、C不通,通过端口转发解决A与C的互通问题,网上找到有人写的代码,加了一些注释直接用了,或许在某些场景下可以有更复杂的应用也不好说,代码如下:

本文代码来自:#http://www.tuicool.com/articles/VRNzaq
socket相关学习:http://yangrong.blog.51cto.com/6945369/1339593/

也可以通过这个端口转发做监控噢、

# -*- coding: utf-8 -*-
import socket
import threading

# 端口映射配置信息
CFG_REMOTE_IP = '192.168.23.133' #要转发的IP
CFG_REMOTE_PORT = 80 #要转发的端口
CFG_LOCAL_IP = '0.0.0.0' #连接IP白名单
CFG_LOCAL_PORT = 5210 #连接的端口号

# 接收数据缓存大小
PKT_BUFF_SIZE = 2048

#调试日志封装
def send_log(content):
    print content
    return

#单向流数据传递
def tcp_mapping_worker(conn_receiver, conn_sender):
    #开始消息循环
    while True:
        try:
            #接受数据
            data = conn_receiver.recv(PKT_BUFF_SIZE)
        except Exception:
            send_log('Event: Connection closed.')
            break
        #没有数据时,打印信息
        if not data:
            send_log('Info: No more data is received.')
            break
        #传递消息
        try:
            conn_sender.sendall(data)
        except Exception:
            send_log('Error: Failed sending data.')
            break

        # send_log('Info: Mapping data > %s ' % repr(data))
        send_log('Info: Mapping > %s -> %s > %d bytes.' % (conn_receiver.getpeername(), conn_sender.getpeername(), len(data)))

    conn_receiver.close()
    conn_sender.close()

    return

#端口映射请求处理
def tcp_mapping_request(local_conn, remote_ip, remote_port):
    #建立TCP流
    remote_conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        #连接要转发的ip和端口
        remote_conn.connect((remote_ip, remote_port))
    except Exception:
        local_conn.close()
        send_log('Error: Unable to connect to the remote server.')
        return
    #把args参数传给tcp_mapping_worker函数做并发处理,开始线程
    threading.Thread(target=tcp_mapping_worker, args=(local_conn, remote_conn)).start()
    threading.Thread(target=tcp_mapping_worker, args=(remote_conn, local_conn)).start()

    return

#端口映射函数
def tcp_mapping(remote_ip, remote_port, local_ip, local_port):
    #建立TCP流
    local_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #绑定IP和端口
    local_server.bind((local_ip, local_port))
    #指定挂起数,开始监听端口
    local_server.listen(5)
    #打印日志
    send_log('Event: Starting mapping service on ' + local_ip + ':' + str(local_port) + ' ...')
    #开始消息循环
    while True:
        try:
            #接受消息并返回
            (local_conn, local_addr) = local_server.accept()
        except KeyboardInterrupt, Exception:
            local_server.close()
            send_log('Event: Stop mapping service.')
            break
        #把args参数传给tcp_mapping_request函数做并发处理,开始线程
        threading.Thread(target=tcp_mapping_request, args=(local_conn, remote_ip, remote_port)).start()
        #打印日志
        send_log('Event: Receive mapping request from %s:%d.' % local_addr)
    return

# 主函数
if __name__ == '__main__':
    tcp_mapping(CFG_REMOTE_IP, CFG_REMOTE_PORT, CFG_LOCAL_IP, CFG_LOCAL_PORT)

发表评论

电子邮件地址不会被公开。 必填项已用*标注