Python3 TCP代理服务器(asyncio协程版)

Python3 TCP代理服务器 异步IO方式编写的代码

一、使用说明

  1. 支持TCP基于端口映射模式:监听本地某端口,数据转发到远程某IP+端口。
  2. 支持TCP转socks服务器模式:这种模式下解决某个应用程序自身不支持socks代理但是希望通过代理服务器进行网络访问的场景。

二、源代码

#!/usr/bin/python3
#-*- coding: utf-8 -*-

import asyncio
import hexdump
import aiohttp_socks

class tcpproxy:
    def __init__(self, remote_ip, remote_port, socks5_url=None):
        self.__remote_ip = remote_ip
        self.__remote_port = remote_port

        self.__socks5_url = socks5_url
        
    async def __copy_data_thread(self, info, reader, writer):
        addr = writer.get_extra_info('peername')
    
        while True:
            chunk = await reader.read(1024)
            if not chunk:
                break
            print("{0}:{1}".format(info, addr))
            hexdump.hexdump(chunk)
            writer.write(chunk)
            await writer.drain()

        print("close sock[{0}]:{1}".format(info, addr))
        writer.close()

    async def accept_handle(self, a_reader, a_writer):
        c_reader = None
        c_writer = None
        
        if socks5_url == None:
            c_reader, c_writer = await asyncio.open_connection(
                host = self.__remote_ip, 
                port = self.__remote_port
                )
        else:
            c_reader, c_writer = await aiohttp_socks.open_connection(
                proxy_url = socks5_url,
                host = self.__remote_ip, 
                port = self.__remote_port
                )

        dltasks = set()
        dltasks.add(asyncio.ensure_future(self.__copy_data_thread('c->a', c_reader, a_writer)))
        dltasks.add(asyncio.ensure_future(self.__copy_data_thread('a->c', a_reader, c_writer)))
        dones, dltasks = await asyncio.wait(dltasks, return_when=asyncio.FIRST_COMPLETED)

def main(local_ip, local_port, remote_ip, remote_port, socks5_url=None):
    tp = tcpproxy(remote_ip, remote_port, socks5_url)
    
    loop = asyncio.get_event_loop()
    coro = asyncio.start_server(tp.accept_handle, local_ip, local_port, loop=loop)
    server = loop.run_until_complete(coro)

    print('Serving on {}'.format(server.sockets[0].getsockname()))
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass

    server.close()
    loop.run_until_complete(server.wait_closed())
    loop.close()

if __name__ == "__main__":
    #socks5_url = 'socks5://127.0.0.1:7000'

    main(
        local_ip = '0.0.0.0', 
        local_port = 22, 
        remote_ip = 'xx.xx.xx.xx', 
        remote_port = 22, 
        socks5_url = None
        )
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值