asyncore confusion

asyncore confusion

Postby metulburr » Tue Apr 15, 2014 7:32 pm

If i am correct, it looks like Twisted is still not fully supported in python3. I havent gone into much Twisted since it wasnt python3.x supported, so i normally used sockets for networking things before. However sockets is looking to be a pain in the ass for making just a basic chat server, let alone my plans for it.

My intentions are to create a game where users can connect to my server. I would like my game to be python2.x/python3.x supported, so i think if that is the case, my only solution is to use sockets. I see a ton of examples using sockets for basic chat back and forth from the client and server. That is all fine and dandy, but the game would requre numerous clients, 7-10 people talking to the server at the same time. asyncore appears to be the answer for python3.x. What is different from asyncore and sockets though? Why does sockets block and asyncore module does not block?

EDIT:
Apparently i am in way over my head. Very bad at networking. I looked at the asyncore module and pretty much rolled my eyes as i have no idea what is going on in there. Anyways...I am not even sure how to use the asyncore module as any other clients past the first one gets a socket.error Address already in use.

2nd client
Code: Select all
metulburr@arch ~ $ python3 aserver.py '' 2003
Traceback (most recent call last):
  File "aserver.py", line 27, in <module>
    s = Server(sys.argv[1], int(sys.argv[2]))
  File "aserver.py", line 8, in __init__
    self.bind(('', port))
  File "/usr/local/lib/python3.2/asyncore.py", line 337, in bind
    return self.socket.bind(addr)
socket.error: [Errno 98] Address already in use
metulburr@arch ~  $



server
Code: Select all
import asyncore, socket, sys

class Server(asyncore.dispatcher):
    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.bind(('', port))
        self.listen(1)

    def handle_accept(self):
        socket, address = self.accept()
        print('Connection by {}'.format(address))
        EchoHandler(socket)

class EchoHandler(asyncore.dispatcher_with_send):
    # dispatcher_with_send extends the basic dispatcher to have an output
    # buffer that it writes whenever there's content
    def handle_read(self):
        self.out_buffer = self.recv(1024)
        if not self.out_buffer:
            self.close()
        i = input('> ')
        #self.sock.send(i.encode())
        self.out_buffer += "ECHO FROM SERVER".encode() + self.out_buffer

s = Server(sys.argv[1], int(sys.argv[2]))
asyncore.loop()


client
Code: Select all
import asyncore, socket, sys

class Client(asyncore.dispatcher_with_send):
    def __init__(self, host, port, message):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect((host, port))
        self.out_buffer = message

    def handle_close(self):
        self.close()

    def handle_read(self):
        print('Received {}'.format(self.recv(1024)))
        i = input('> ')
        self.out_buffer = i.encode()
        #self.close()

c = Client(sys.argv[1], int(sys.argv[2]), 'Hello, world'.encode())
asyncore.loop()


Running this, the server can send only one line back to the client, and the client cant sent anything. Plus if a second client tried to connect, it fails with the traceback above. I assumed it would be the same as sockets, and just threw the recv and send in a while loop for the server,
server.EchHandler
Code: Select all
    def handle_read(self):
        while True:
            self.out_buffer = self.recv(1024)
            if not self.out_buffer:
                self.close()
            i = input('> ')
            #self.sock.send(i.encode())
            self.out_buffer += "ECHO FROM SERVER".encode() + self.out_buffer


but then i get the traceback
Code: Select all
metulburr@arch ~  $ python aserver.py '' 2003
Connection by ('127.0.0.1', 45606)
> test
error: uncaptured python exception, closing channel <__main__.EchoHandler connected 127.0.0.1:45606 at 0x7fece630f198> (<class 'BlockingIOError'>:[Errno 11] Resource temporarily unavailable [/usr/lib/python3.4/asyncore.py|read|83] [/usr/lib/python3.4/asyncore.py|handle_read_event|442] [aserver.py|handle_read|21] [/usr/lib/python3.4/asyncore.py|recv|379])
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1363
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: asyncore confusion

Postby metulburr » Tue Apr 15, 2014 11:06 pm

Another complete different example i came across, the client keeps getting connection refused (on every port i tried)
Code: Select all
import asyncore, sys, threading

class Server(asyncore.dispatcher):
    def __init__(self, host='', port=6666):
        self.connections = []

    def handle_accept(self):
        handler = EchoHandler(self.sock, self);
        self.connections.append(self.sock)

    def remove_channel(self, sock):
        if sock in self.connections:
            self.connections.remove(sock)

class EchoHandler(asyncore.dispatcher_with_send):
    def __init__(self, sock, server):
        self.server = server

    def handle_read(self):
       
        while True:
            datos = self.recv(1024);
            if datos:
                print(datos);
                self.out_buffer += 'I echo you: ' + datos

    def handle_close(self):
        self.server.remove_channel(self)
        self.close()


class ServerThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True # if thread is a daemon, it'll be killed when main program exits
        self.cliente = Server()
        self.start()

    def run(self):
        print('Starting server thread...')
        asyncore.loop()

thread = ServerThread()

while True:
    msg = input('Enter IP and message divided by semicolon: ')

    if msg == 'exit':
        break
    print(msg)
    ip, data = msg.split(';')
    for sock in thread.cliente.connections:
        if sock.addr[0] == ip:
            sock.out_buffer += data
            break



Does anyone have a working example of a server/client with asyncore?
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1363
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY


Return to Networking

Who is online

Users browsing this forum: No registered users and 2 guests