Pergunta

I have been trying to make a simple server that me and my friend will be able to play a game like go fish or another simple card game on. I am just learning how to use the asyncore class and I am having a problem. The program will not connect when there is no server up, but when there is it says it connects successfully, however it never calls the handle_accept method, and if i even get rid of the handle_accept method it will still connect, or at least not run into any errors.
I have been using this website and descriptions of the python asyncore method but I do not understand what I am doing wrong.
http://parijatmishra.wordpress.com/2008/01/04/writing-a-server-with-pythons-asyncore-module/

I have included the code for both of the UIs and the Server and Client code.

Server UI

from Tkinter import *
from Server import *
import asyncore

class UI:

    # initialize UI
    def __init__(self, master):

        # create frame1
        frame1 = Frame(master, width=200, height=50)
        frame1.pack()

        # create frame2
        frame2 = Frame(master, width=200, height=50)
        frame2.pack()

        # create start button
        self.start = Button(frame1, text='Start Server', command=lambda: self.start_server())
        self.start.pack()

        # create end button
        self.stop = Button(frame1, text='Stop Server', command=lambda: self.stop_server())
        self.stop.pack()

        # create label
        self.label = Label(frame2)
        self.label.pack()

        # keep set size
        frame1.pack_propagate(0)
        frame2.pack_propagate(0)

    def start_server(self):

        try:
            self.server = Server()
            asyncore.loop()
        except:
            self.label.config(text='Error. A server is already running.')
        else:
            self.label.config(text='Server successfully started')

    def stop_server(self):

        try:
            self.server.stop() 
        except:
            self.label.config(text='Error. No server is running.')
        else:
            self.label.config(text='Server successfully stopped.')    

root = Tk()
ui = UI(root)
root.mainloop()

Client UI

from Tkinter import *
from Client import *
import asyncore

class UI:

    # initialize the UI
    def __init__(self, master):

        # create frame1
        frame1 = Frame(master)
        frame1.pack()

        # create frame2
        frame2 = Frame(master, width=200, height=50)
        frame2.pack()

        # create frame3
        frame3 = Frame(master, width=200, height=50)
        frame3.pack()

        # create connect button
        self.connect = Button(frame1, text='Connect', command=lambda: self.connect_to_server())
        self.connect.pack(side=RIGHT)

        # create disconnect button
        self.disconnect = Button(frame1, text='Disconnect', command=lambda: self.disconnect_from_server())
        self.disconnect.pack()

        # create label
        self.label = Label(frame2, text='Enter host\'s ip')
        self.label.pack()

        # create entry box
        self.entry = Entry(frame3)
        self.entry.pack()

        # keep set size
        frame2.pack_propagate(0)
        frame3.pack_propagate(0)

    # connect to a server    
    def connect_to_server(self):

        ip = self.entry.get()

        try:
            self.client = Client(ip)
            asyncore.loop()
        except:
            self.label.config(text='Error. Unable to connect.')
        else:
            self.label.config(text='Successfully connected.')

    # disconnect from a server    
    def disconnect_from_server(self):
        try:
            self.client.disconnect()
        except:
            self.label.config(text='Error. Not connected to anything.')
        else:
            self.label.config(text='Successfully disconnected.')


root = Tk()
ui = UI(root)
root.mainloop()

Server class

from socket import *
import asyncore

class Server(asyncore.dispatcher):

    # initialize a server
    def __init__(self):

        asyncore.dispatcher.__init__(self)
        self.host = '127.0.0.1'
        self.port = 50000 
        self.size = 1024
        self.s = socket(AF_INET, SOCK_STREAM)
        self.s.bind((self.host,self.port)) 
        self.s.listen(5)


    def stop(self):

        self.s.close()

    def readable(self):
        return True

    def handle_accept(self):
        client, addr = self.s.accept()
        print 'Incoming connection from ', repr(addr) 

Client class

from socket import *
import asyncore

class Client(asyncore.dispatcher):

    def __init__(self, ip):

        asyncore.dispatcher.__init__(self)
        self.address = ip
        self.port = 50000 
        self.size = 1024
        self.s = socket(AF_INET, SOCK_STREAM)  
        self.s.connect((self.address, self.port)) 

    def disconnect(self):

        self.s.close()

    def send_data(self, msg):

        self.s.send(msg)

    def handle_connect(self):
        print 'Trying to connect'
Foi útil?

Solução

handle_connect is called whether the connection attempt succeeds or fails. It is called to notify you that the connection attempt is complete, not that it has definitely succeeded. You have to check to determine whether it has succeeded.

Instead of working out the various mysteries of asyncore, you should switch to using Twisted instead. Twisted is actively maintained, better documented, provides much more functionality, and abstracts more of the irrelevant low-level details of networking away from you.

See the server and client howtos to get started.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top