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

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

```

代码在此

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值