Python3 TCP代理服务器 异步IO方式编写的代码
一、使用说明
- 支持TCP基于端口映射模式:监听本地某端口,数据转发到远程某IP+端口。
- 支持TCP转socks服务器模式:这种模式下解决某个应用程序自身不支持socks代理但是希望通过代理服务器进行网络访问的场景。
二、源代码
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__":
main(
local_ip = '0.0.0.0',
local_port = 22,
remote_ip = 'xx.xx.xx.xx',
remote_port = 22,
socks5_url = None
)