asyncio流阅读器不是在while循环中读取

时间:2016-06-20 16:51:38

标签: python python-3.x bittorrent coroutine python-asyncio

我正在尝试连接到其他对等方并使用asyncio流API从他们那里获取数据,我正在努力工作。但是,我无法异步从所有连接的对等方获取数据。到目前为止,我只能从第一个对等体获取数据,但是从其他对等体读取数据似乎被阻止了。我没有收到来自其他对等方的chunk = await peer.reader.read()的响应,代码阻止其他代码执行。

我对asyncio很新,任何帮助都会受到赞赏!

输出:

2016-06-20 12:16:26,302 - main.torrent_client - ERROR - [Errno 61] Connect call failed ('74.101.0.24', 6881), {'port': 6881, 'host': '74.101.0.24'}
2016-06-20 12:16:26,397 - main.torrent_client - INFO - connected with peer {'port': 14122, 'host': '80.94.76.7'}
2016-06-20 12:16:26,397 - main.torrent_client - INFO - wating for chunks from {'port': 14122, 'host': '80.94.76.7'}
2016-06-20 12:16:26,454 - main.torrent_client - INFO - connected with peer {'port': 61571, 'host': '83.132.145.93'}
2016-06-20 12:16:26,454 - main.torrent_client - INFO - wating for chunks from {'port': 61571, 'host': '83.132.145.93'}
2016-06-20 12:16:26,460 - main.torrent_client - INFO - connected with peer {'port': 36657, 'host': '79.114.230.255'}
2016-06-20 12:16:26,460 - main.torrent_client - INFO - wating for chunks from {'port': 36657, 'host': '79.114.230.255'}
2016-06-20 12:16:26,464 - main.torrent_client - ERROR - [Errno 61] Connect call failed ('77.235.138.250', 6881), {'port': 6881, 'host': '77.235.138.250'}
2016-06-20 12:16:26,507 - main.torrent_client - INFO - connected with peer {'port': 21426, 'host': '78.176.46.111'}
2016-06-20 12:16:26,508 - main.torrent_client - INFO - wating for chunks from {'port': 21426, 'host': '78.176.46.111'}
2016-06-20 12:16:26,545 - main.torrent_client - INFO - connected with peer {'port': 14474, 'host': '88.244.155.118'}
2016-06-20 12:16:26,545 - main.torrent_client - INFO - wating for chunks from {'port': 14474, 'host': '88.244.155.118'}
2016-06-20 12:16:34,042 - main.torrent_client - ERROR - [Errno 51] Connect call failed ('95.10.195.101', 22665), {'port': 22665, 'host': '95.10.195.101'}
2016-06-20 12:17:41,387 - main.torrent_client - ERROR - [Errno 60] Connect call failed ('93.34.36.131', 13311), {'port': 13311, 'host': '93.34.36.131'}
2016-06-20 12:17:41,387 - main.torrent_client - ERROR - [Errno 60] Connect call failed ('204.237.81.10', 52074), {'port': 52074, 'host': '204.237.81.10'}

2016-06-20 12:18:26,170 - main.torrent_client - DEBUG - read from peer {'port': 14122, 'host': '80.94.76.7'}

2016-06-20 12:18:26,171 - main.torrent_client - INFO - chunk from {'port': 14122, 'host': '80.94.76.7'}: b'\x13BitTorrent protocol\x00\x00\x00\x00\x00\x10\x00\x00#\xb0\x93\x9ez\xc8\xb9\xb0\x1c\xda\xf0\x1f\x98\x8b\x9f\xfb\xbeD\xdd\xe2-lt0D20-O.\xa8q\xbd\xd9\xd2\x96\x0f\xf2t>\x00\x00\x06#\x05\xff\xff\xff\xff\xff\xff\f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'

2016-06-20 12:18:26,174 - main.torrent_client - INFO - Sent INTERESTED message to Peer {'port': 14122, 'host': '80.94.76.7'}

2016-06-20 12:18:26,174 - main.torrent_client - INFO - wating for chunks from {'port': 14122, 'host': '80.94.76.7'}

2016-06-20 12:18:26,174 - main.torrent_client - DEBUG - read from peer {'port': 14122, 'host': '80.94.76.7'}

2016-06-20 12:18:26,174 - main.torrent_client - INFO - no chunk from {'port': 14122, 'host': '80.94.76.7'}

...and program hangs here

client.py:

async def _connection_handler(self, peer):
    # listen for incoming data from peers

    self.logger.info('connected with peer {}'.format(peer.ip))
    peer.writer.write(self._hand_shake())

    while True:

        self.logger.info('wating for chunks from {}'.format(peer.ip))
        chunk = await peer.reader.read()

        if not chunk:
            self.logger.info('no chunk from {}'.format(peer.ip))
            break

        self.logger.info('chunk from {}: {}'.format(peer.ip, chunk))
        if chunk[1:20].lower() == b'bittorrent protocol':

            info_hash = chunk[28:48]
            if self.torrent.info_hash != info_hash:
                self._close_connection(peer)
            else:
                chunk = chunk[68:]
                peer.writer.write(INTERESTED)
                await peer.writer.drain()
                self.logger.info('Sent INTERESTED message to Peer {}'.format(peer.ip))

        # await self._process_data_from_peer(peer)

async def _connect_to_peer(self, peer):

    try:
        reader, writer = await asyncio.open_connection(
                peer.ip['host'], peer.ip['port'])

        peer.reader = reader
        peer.writer = writer

        await self._connection_handler(peer)
    except ConnectionRefusedError as e:
        self.logger.error('{}, {}'.format(e, peer.ip))
    except (TimeoutError, OSError) as e:
        self.logger.error('{}, {}'.format(e, peer.ip))

        # pp = PeerProtocol(
        #         self.torrent,
        #         self.data_buffer,
        #         self.blocks_requested,
        #         self.pieces_downloaded
        #         )
        # await self.loop.create_connection(
        #         lambda: pp,
        #         peer['host'],
        #         peer['port']
        #     )


async def connect_to_peers(self):
    await asyncio.gather(
            *[self._connect_to_peer(peer) for peer in self.peers],
            )

main.py:

def main():
    filename = '../street-fighter.torrent'
    client = TorrentClient(filename, loop)

    asyncio.ensure_future(client.connect_to_peers())

    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    finally:
        loop.close()


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    main()

0 个答案:

没有答案