吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5170|回复: 20
收起左侧

[Python 转载] 【闹腾】python实现本地流量转发

[复制链接]
天域至尊 发表于 2020-3-1 23:39
本帖最后由 天域至尊 于 2020-3-1 23:42 编辑

前一段时间在家上班,家里有一个老的办公软件希望能够映射到公网,奈何端口什么的都是写死的,只能在本地端口进行链接,就写了一个流量转发的小脚本,来实现。

我所实现的流量转发就是把发往本地ip某个端口的数据转发到别的地方。当然,Linux和windows都有现成的东西,所以如果大家需要,建议使用系统自带的功能,好用且稳定。
举例Windows的转发命令(需要管理员权限)
[Bash shell] 纯文本查看 复制代码
netsh interface portproxy add v4tov4 listenaddress="本地ip"  listenport=本地端口 connectaddress="服务端IP" connectport=服务端端口

Linux和其他系统的命令,建议大家自己找找

下面是我自己编写的python脚本源码
python脚本(无需管理员权限)
[Python] 纯文本查看 复制代码
import socket,time,threading

#这里填写本地监听的ip和端口
ip='127.0.0.1'
port=0

#这列填写公网ip和端口
send_ip=''
send_port=0

#以下部分无需修改
#这是用来存放转发到公网数据的队列
outList=[]
#这是用来存放转发到内网数据的队列
inList=[]
#这是队列的锁,防止竞争
outLock=False
inLock=False
#这是用来标记是否发送的断开连接信息
runStation=True

def  in_get(sock):
    '''
    该函数负责监听本地的端口,传入的sock,收到数据后,将其增加到转发到公网的队列中
    '''
    global outLock,outList,inLock,inList,runStation
    while runStation:
        try:
            try:
                data=sock.recv(8192)
                time.sleep(0.1)
            except Exception as ie:
                print(+str(ie))
                time.sleep(0.1)

            #如果内网发送的空数据,即代表需要断开连接(管家婆特性)
            if data==b'':
                runStation=False
            #这里循环等待锁关闭
            while (outLock==True):
                time.sleep(0.01)
            else:
                #打开锁,防止竞争,将数据增加到队列后,关闭锁
                outLock=True
                outList.append(data)
                outLock=False
        except Exception as err:
            print('inget'+str(err))
            print(type(sock))

def in_out(sock):
    '''
    该函数负责循环检查对内发送的队列是是否有数据
    发现存在数据后,将数据转发到内部,并且清空对内转发的队列
    '''
    global outLock,outList,inLock,inList
    while runStation:
        try:
            if len(inList)!=0:
                #这里是判断对内转发的锁是否开启
                while (inLock==True):
                    time.sleep(0.01)
                else:
                    #关闭锁,发送数据,清空队列,打开锁
                    inLock=True
                    for i in inList:
                        sock.send(i)
                    inList.clear()
                    inLock=False
            else:
                time.sleep(0.001)
        except Exception as err:
            print(err)

def  out_get(sock):
    '''
    该函数负责监听外网数据,收到数据后,将其增加到对内转发队列
    '''
    global outLock,outList,inLock,inList
    while runStation:
        try:
            data=sock.recv(8192)
            time.sleep(0.1)
            while (inLock==True):
                time.sleep(0.01)
            else:
                inLock=True
                inList.append(data)
                inLock=False
        except Exception as err:
            print('outget'+str(err))

def out_out(sock):
    '''
    该函数负责对外转发,发现对外转发队列有数据后,判断锁状态,发送数据后清空队列,关闭锁。
    '''
    global outLock,outList,inLock,inList
    while runStation:
        try:
            if len(outList)!=0:
                while (outLock==True):
                    time.sleep(0.01)
                else:
                    outLock=True
                    for i in outList:
                        if i!=b'':
                            sock.send(i)
                    outList.clear()
                    outLock=False
            else:
                time.sleep(0.001)
        except Exception as err:
            print(err)


def tcplink(sock, addr,ip,port):
    '''
    内部建立起连接后,该函数负责统一处理,其中传入的ip和port指的是外网的。
    '''
    global runStation
    print('Accept new connection from %s:%s...' % addr)
    #与外网建立连接
    s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 建立连接:
    s1.connect((ip, port))
    #启动线程,开始监听内网
    inGet = threading.Thread(target=in_get, args=(sock,))
    inGet.start()
    #启动多个内网发送线程,提高速度
    inOut = threading.Thread(target=in_out, args=(sock,))
    inOut.start()
    inOut2 = threading.Thread(target=in_out, args=(sock,))
    inOut2.start()
    inOut3 = threading.Thread(target=in_out, args=(sock,))
    inOut3.start()
    #启动一个外网监听进程,开始监听
    outGet = threading.Thread(target=out_get, args=(s1,))
    outGet.start()
    #启动多个外网发送线程,提高速度
    outOut = threading.Thread(target=out_out, args=(s1,))
    outOut.start()
    outOut1 = threading.Thread(target=out_out, args=(s1,))
    outOut1.start()
    outOut2 = threading.Thread(target=out_out, args=(s1,))
    outOut2.start()
    #在发现连接断开后,即断开内网和外网的套接字
    while runStation:
        time.sleep(0.5)
    else:
        try:
            sock.close()
            s1.close()
        except Exception:
            pass
    print('Connection from %s:%s closed.' % addr)

#新建套接字
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#绑定本地端口
s.bind((ip, port))
#设置最大连接数
s.listen(5)

while True:
    # 接受一个新连接:
    sock1, addr = s.accept()
    #初始化数据
    runStation=True
    outList=[]
    inList=[]
    outLock=False
    inLock=False
    runStation=True
    # 创建新线程来处理TCP连接:
    t = threading.Thread(target=tcplink, args=(sock1, addr,send_ip,send_port))
    t.start()

这样运行python脚本,他就会监听某一个本地端口,将发送到本地端口的tcp流量转发出去,并且把回复的数据转发到本地端口。使运行的程序以为链接的是本地的服务。

当然,该脚本的用处并不仅仅限于此处,相信大家懂得。

原创作品,转载请声明出处。
另:该源码也发布到本人的CSDN博客,请大家不要误会抄袭。

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
cangyue0609 + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

jmc06 发表于 2022-2-4 19:07
楼主你简直是个天才,你写的红字也是意味深远。。。我已经get到了你的意思,哈哈~~
 楼主| 天域至尊 发表于 2020-3-4 12:13
py看考场 发表于 2020-3-3 13:48
没有学习过网络编程,这里的流量转发是代{过}{滤}理的意思吗

差不多吧,把发往本地的流量转发到别的地方
雷_影 发表于 2020-3-1 23:49
yinsugege 发表于 2020-3-1 23:58
有技术真好            
过往温柔的你 发表于 2020-3-2 00:13
撒功能,百度yun?
xiaoxi2011 发表于 2020-3-2 00:28
学习了,谢谢分享
闰土168 发表于 2020-3-2 07:46
挺方便啊
cangyue0609 发表于 2020-3-2 12:04
一般负载应用时用的比较多,可以转发到不固定ip地址
jixiangyh 发表于 2020-3-2 19:40
思路不错,谢谢分享~~
zucker 发表于 2020-3-2 20:03
当然,该脚本的用处并不仅仅限于此处,相信大家懂得。

我不懂
头像被屏蔽
mokson 发表于 2020-3-3 11:13
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 08:42

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表