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'
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.