当前位置:   article > 正文

python asyncio socket_用 Python 的 asyncio 库写了一个简单的 socket5 代理,莫名其妙的卡住,请大家帮忙看下!...

asyncio open_connection 卡顿

1462326016

2019-06-28 20:25:52 +08:00

感谢大家的帮助,改成全双工已经没有问题了。

```

# -*- coding: utf-8 -*-

import asyncio

from struct import unpack, pack

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()))

```

代码在此

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/96149
推荐阅读
相关标签
  

闽ICP备14008679号