Skip to content

Instantly share code, notes, and snippets.

@libra146
Created July 17, 2020 01:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save libra146/34d8d041a39c7a60df7268c60e3b18fa to your computer and use it in GitHub Desktop.
Save libra146/34d8d041a39c7a60df7268c60e3b18fa to your computer and use it in GitHub Desktop.
脚本
# -*- coding: utf-8 -*-
import asyncio
from struct import unpack, pack
"""
socket5协议学习
"""
async def handle_echo(reader, writer):
data = await reader.read(1024 * 64)
addr = writer.get_extra_info('peername')
print(f"connect from {addr!r}")
if len(data) < 3:
print('too short...')
writer.close()
return
result = unpack('!BBB', data[:3])
writer.write(b'\x05\x00')
await writer.drain()
data = await reader.read(1024 * 64)
result = unpack('!4B', data[:4])
if result[0] == 5 and result[1] == 1 and result[3] == 3:
host_len = unpack('!B', data[4:5])[0]
host = data[5:host_len + 5].decode()
port = unpack('!H', data[host_len + 5:])[0]
print(f'len {host_len},host {host},port {port}')
try:
reader_remote, writer_remote = await asyncio.open_connection(host, port)
writer.write(pack('!5B', 5, 0, 0, 3, host_len) + host.encode() + pack('!H', port))
await writer.drain()
print(f'connect success!{host}')
except (TimeoutError, ConnectionRefusedError) as _:
print(f'connect failed!{host}')
writer.write(pack('!5B', 5, 3, 0, 3, host_len) + host.encode() + pack('!H', port))
await writer.drain()
writer.close()
return
up_stream = _pipe(reader, writer_remote, host)
down_stream = _pipe(reader_remote, writer, host)
await asyncio.gather(up_stream, down_stream)
if result[0] == 5 and result[1] == 1 and result[3] == 1:
ip = '.'.join([str(a) for a in unpack('!BBBB', data[4:8])])
port = unpack('H', data[8:10])[0]
print(f'ip {ip},port {port}')
try:
reader_remote, writer_remote = await asyncio.open_connection(ip, port)
writer.write(pack('!8B', 5, 0, 0, 1, *unpack('!BBBB', data[4:8])) + pack('!H', port))
await writer.drain()
print(f'connect success!{ip}')
except (TimeoutError, ConnectionRefusedError) as _:
print(f'connect failed!{ip},{repr(_)}')
writer.write(pack('!8B', 5, 3, 0, 1, *unpack('!BBBB', data[4:8])) + pack('!H', port))
await writer.drain()
writer.close()
return
up_stream = _pipe(reader, writer_remote, ip)
down_stream = _pipe(reader_remote, writer, ip)
await asyncio.gather(up_stream, down_stream)
async def _pipe(reader, writer, host):
while reader.at_eof:
try:
data = await reader.read(1024 * 64)
if not data:
writer.close()
break
except (ConnectionAbortedError, ConnectionResetError) as _:
writer.close()
print(f'{host} 异常退出 {repr(_)}')
break
try:
writer.write(data)
await writer.drain()
except (ConnectionAbortedError, ConnectionResetError) as _:
writer.close()
print(f'{host} 异常退出 {repr(_)}')
break
print(f'{host} 退出')
async def main():
server = await asyncio.start_server(
handle_echo, '0.0.0.0', 3333)
addr = server.sockets[0].getsockname()
print(f'Serving on {addr}')
async with server:
await server.serve_forever()
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(main()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment