asyncore: handle_accept() question?

C

Chris

Here's the idea:

I have a listen_server listening to a specific port. A connection
object connects to it remotely, and then the communication begins.
Once connected, I would like to have the server act no differently
than the client (i.e. use the connection class to handle the
connection). This way rather than having a typical server and
client(producer/consumer) I have two peers.

class listen_server(asyncore.dispatcher):
def __init__(self, port): ### Basic Server Stuff ###
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind(('', port))
self.listen(5)

def handle_accept(self):
conn, addr = self.accept()
print conn.fileno() ## this always prints a number
print 'connection accepted' ## this always prints
newcon = connection(sock=conn) ## error happens here

class connection(asyncore.dispatcher):
def __init__(self, host = None, port = None, sock = None):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr() # needed?

if host and port: self.connect((host, port))
if sock is not None:
print 'setting socket'
self.set_socket(sock)

def handle_read(self):
data = self.recv(4096)

def handle_write(self):
pass

def handle_connect(self):
print 'connected'

def handle_close(self):
print 'closed connection'
self.close()

Here is my output:
---------------------------
connection accepted
setting socket
Traceback (most recent call last):
File "test.py", line 66, in ?
asyncore.loop()
File "/usr/lib/python2.2/asyncore.py", line 206, in loop
poll_fun (timeout, map)
File "/usr/lib/python2.2/asyncore.py", line 83, in poll
r,w,e = select.select (r,w,e, timeout)
select.error: (9, 'Bad file descriptor')

My basic problem is that I don't know any other way to 'hand off' the
incoming connection - if there is a better way to do this please let
me know. conn.fileno() appears to work, and I don't understand why
this error comes up.

Any ideas?

Thanks,
Chris
 
E

Erik Max Francis

Chris said:
self.set_reuse_addr() # needed?

This is definitely not needed in the connection; it's only useful in the
server. (I doubt this is your problem.)
My basic problem is that I don't know any other way to 'hand off' the
incoming connection - if there is a better way to do this please let
me know. conn.fileno() appears to work, and I don't understand why
this error comes up.

Any ideas?

It looks like you're trying to do too much in your connection class
constructor. In the way you're using it, after accept is called, the
connection socket is already open and ready. You need not create or
initialize it; the fact that you're doing so is invariably what's
causing your error, although I'll admit I haven't tried to actually
reproduce it. In fact, after accept, initializing a connection is
simpler than simple. All you need to do is pass the socket into the
asyncore.dispatcher/asynchat.async_chat constructor:

class Connection(asyncore.dispatcher):
def __init__(self, host, port, sock):
asyncore.dispatcher.__init__(self, sock)
# all done, your connection is ready to go

As it stands, you're creating new sockets and attempting to connect to
the connection address of the _accepted_ socket (where there isn't a
server listening), so it looks like you're getting a partially
initialized socket which would explain your problem.
 
N

Ng Pheng Siong

According to Chris said:
class connection(asyncore.dispatcher):
def __init__(self, host = None, port = None, sock = None):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr() # needed?

if host and port: self.connect((host, port))
if sock is not None:
print 'setting socket'
self.set_socket(sock)

It's been a while since I did asyncore stuff, so I may be off-base. From
asyncore.py:

def create_socket (self, family, type):
self.family_and_type = family, type
self.socket = socket.socket (family, type)
[...]

def set_socket (self, sock, map=None):
self.socket = sock
[...]

Your code calls self.create_socket, which binds self.socket to a newly
created socket, then it calls self.set_socket(sock), which binds
self.socket to your accepted socket.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top