raector.py
#coding:utf-8
'''
create on 2017-04-20
@author: sandy
'''
import event_demultiplexer
class Reactor(object):
def __init__(self):
self.runing = True
self.demultiplexer = event_demultiplexer.EpollDemultiplexer()
def registerHandler(self,handler,event):
return self.demultiplexer.addEvent(handler,event)
def modifyHandler(self,handler,event):
return self.demultiplexer.modifyEvent(handler,event)
def removeHandler(self,handler):
return self.demultiplexer.removeEvent(handler)
def run(self):
self.startRunning()
self.mainLoop()
def stop(self):
self.stopRuning()
del self.demultiplexer
def startRunning(self):
self.runing = True
def stopRuning(self):
self.runing = False
def mainLoop(self):
while self.runing:
self.demultiplexer.waitEvents(1)
instance = Reactor()
event_demultiplexer.py
#coding:utf-8
'''
create on 2017-04-20
@author: sandy
'''
import select
class EventDemultiplexer(object):
def __init__(self):
pass
def waitEvents(self,timeout):
pass
def addEvent(self,handle,event):
pass
def modifyEvent(self,handle,event):
pass
def removeEvent(self,handle):
pass
class EpollDemultiplexer(EventDemultiplexer):
def __init__(self):
self.epoll = select.epoll(1024)
self.handles = {}
def __del__(self):
self.epoll.close()
pass
def waitEvents(self,timeout):
events = self.epoll.poll(timeout)
for fd,event in events:
handle = self.handles[fd]
if event & select.EPOLLHUP or event & select.EPOLLERR:
handle.handleError(fd)
elif event & select.EPOLLIN:
handle.handleRead(fd)
elif event & select.EPOLLOUT:
handle.handleWrite(fd)
def addEvent(self,handle,event):
fd = handle.fileno()
self.handles[fd] = handle
self.epoll.register(fd,event)
def modifyEvent(self,handle,event):
fd = handle.fileno()
self.handles[fd] = handle
self.epoll.modify(fd,event)
def removeEvent(self,handle):
fd = handle.fileno()
self.handles.pop(fd,None)
self.epoll.unregister(fd)
event_handle.py
#coding:utf-8
'''
create on 2017-04-20
@author: sandy
'''
class EventHandle(object):
def __init__(self):
pass
def fileno(self):
pass
def handleRead(self,fd):
pass
def handleWrite(self,fd):
pass
def handleError(self,fd):
pass
main.py
#coding:utf-8
'''
create on 2017-04-20
@author: sandy
'''
import socket
import select
import event_handle
import reactor
class ClientHandle(event_handle.EventHandle):
def __init__(self,csocket):
event_handle.EventHandle.__init__(self)
self.csocket = csocket
def fileno(self):
return self.csocket.fileno()
def handleRead(self,fd):
print("Client handleRead fd=",fd)
data = self.csocket.recv(1024)
if len(data) == 0:
print("client close")
reactor.instance.modifyHandler(self,0)
else:
print("received data:",data)
reactor.instance.modifyHandler(self,select.EPOLLOUT)
def handleWrite(self,fd):
print("Client handleWrite fd=",fd)
sendbyte = b"hello world"
byteswritten = self.csocket.send(sendbyte)
if byteswritten == len(sendbyte):
reactor.instance.modifyHandler(self,select.EPOLLIN)
def handleError(self,fd):
print("Client handleError")
reactor.instance.removeHandler(self)
class ServerHandle(event_handle.EventHandle):
def __init__(self,ssocket):
event_handle.EventHandle.__init__(self)
self.ssocket = ssocket
def fileno(self):
return self.ssocket.fileno()
def handleRead(self,fd):
print("ServerHandle handleRead fd=",fd)
if fd == self.fileno():
connection,address = self.ssocket.accept()
print("address=",address)
connection.setblocking(False)
reactor.instance.registerHandler(ClientHandle(connection),select.EPOLLIN | select.EPOLLERR | select.EPOLLHUP)
pass
def handleWrite(self,fd):
print("ServerHandle handleWrite")
def handleError(self,fd):
print("ServerHandle handleError")
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ("0.0.0.0", 8888)
serversocket.bind(server_address)
serversocket.listen(10)
print("server start and listen ip:",server_address)
serversocket.setblocking(False)
serverhandle = ServerHandle(serversocket)
reactor.instance.registerHandler(serverhandle,select.EPOLLIN | select.EPOLLERR | select.EPOLLHUP)
reactor.instance.run()
reactor.instance.removeHandler(serverhandle)
reactor.instance.stop()
serversocket.close()