0

I'm trying to simulate a network using asychronious TCP servers and sockets. I used an example from documentation as a starting point for my task. Here's the code of my server class:

import asyncio
import socket
import Node

class ServerProtocol(asyncio.Protocol):
    def __init__(self, hostNode):
        self.hostNode = hostNode

    def connection_made(self, transport):
        peername = transport.get_extra_info('peername')
        print('Connection from {}'.format(peername))
        self.transport = transport

    def data_received(self, data):
        print('Data received: {!r}'.format(data))
        self.hostNode.processIncomingMessage(data)

class NodeServer:
    def __init__(self, hostNode):
        self.loop = asyncio.get_event_loop()
        self.hostNode = hostNode

    def startListening(self):
        self.coro = self.loop.create_server(ServerProtocol(self.hostNode), '', 0, family=socket.AF_INET)
        server = self.loop.run_until_complete(self.coro)

    def getPortNumber(self):
        print(self.coro.sockets)
        portNumber = self.coro.sockets[0].getpeername()[1]
        print(portNumber)
        return portNumber

I call create_server function with params '', 0 and family=socket.AF_INET because I need to establish IPv4 version and the OS must give appropriate random port to listen. In the code below I'm trying to get a number of port. Documentation says, create_server function returns Server object, and sockets can be retrieved from sockets attribute. But when I run the code, I get following error:

AttributeError: 'generator' object has no attribute 'sockets'

It happens when executing self.coro.sockets

So, that's the issue.

Could someone help me with this, please?

Many thanks.

1 Answer 1

1

The call to create_server returns a coroutine. The server instance which has the sockets attribute is returned when you call run_until_complete. Change the definition of startListening to save the return value of run_until_complete as self.server and modify your getPortNumber definition to use that instead. You also need to change getpeername to getsockname to get the port allocated.

class NodeServer:
    def __init__(self, hostNode):
        self.loop = asyncio.get_event_loop()
        self.hostNode = hostNode

    def startListening(self):
        self.coro = self.loop.create_server(ServerProtocol(self.hostNode), '', 0, family=socket.AF_INET)
        self.server = self.loop.run_until_complete(self.coro)

    def getPortNumber(self):
        print(self.server.sockets)
        portNumber = self.server.sockets[0].getsockname()[1]
        print(portNumber)
        return portNumber
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. It really hepled. Can I ask you another question?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.