异步服务器Python不调用handle_accept或任何其他句柄方法

时间:2012-01-29 16:44:18

标签: python asynchronous asyncore

我一直在尝试制作一个简单的服务器,让我和我的朋友能够像钓鱼或其他简单的纸牌游戏一样玩游戏。我正在学习如何使用asyncore类,我遇到了问题。当没有服务器启动时,程序将无法连接,但是当它有连接成功时它会连接,但它从不调用handle_accept方法,如果我甚至摆脱handle_accept方法它仍将连接,或者至少不运行任何错误。
我一直在使用这个网站和python asyncore方法的描述,但我不明白我做错了什么 http://parijatmishra.wordpress.com/2008/01/04/writing-a-server-with-pythons-asyncore-module/

我已经包含了两个用户界面以及服务器和客户端代码的代码。

服务器用户界面

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()

客户端用户界面

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()

服务器类

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) 

客户端类

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'

1 个答案:

答案 0 :(得分:1)

无论连接尝试成功还是失败,都会调用

handle_connect。它被称为通知您连接尝试是完成,而不是它已经确定成功。您必须检查以确定它是否成功。

而不是解决asyncore的各种谜团,你应该转而使用Twisted代替。扭曲被积极维护,更好地记录,提供更多功能,并抽象出更多与网络无关的低级别细节。

请参阅serverclient如何开始使用。