threading_test.pyreact
#threading #爲何在命令行能夠執行,F5不能執行 #線程處理能致使同步問題 from socketserver import TCPServer,ThreadingMixIn,StreamRequestHandler class Server(ThreadingMixIn,TCPServer):pass class Handler(StreamRequestHandler): def handle(self): addr=self.request.getpeername() print('from',addr) self.wfile.write(b'thanks') print(self.rfile.read(1024).decode()) server=Server(('',1234),Handler) server.serve_forever()
forking_test.py服務器
#forking 分叉 ##Windows 不支持分叉!! ''''分叉佔據資源,而且若是有太多的客戶端時分叉不能很好分叉(儘管如此, 對於合理數量的客戶端,分叉在現代的UNIX或Linux系統中是很高效的,若是有一個多CPU系統那效率更高 )''' from socketserver import TCPServer,ForkingMixIn,StreamRequestHandler class Server(ForkingMixIn,TCPServer):pass class Handler(StreamRequestHandler): def handle(self): addr=self.request.getpeername() print('from',addr) self.wfile.write(b'thanks') server=Server(('',1234),Handler) server.serve_forever()
select_test.pyapp
#asynchronous I/O ''' 只處理在給定時間內真正要進行通訊的客戶端。不須要一直監聽,只要監聽(或讀取)一下子, 而後把它放到其餘客戶端的後面 這是asyncore/asynchat框架和Twisted框架採用的方法,這種功能的基礎是select函數, 若是poll函數可用,那也能夠是它,這兩個函數都來自select模塊。 這兩個函數中,poll的伸縮性更好,但它只能在UNIX系統中使用 select須要3個序列做爲它的必選參數,此外還有一個可選的以秒爲單位的超時時間做爲第4個參數 這些序列是文件描述符整數(或是帶有返回這樣整數的fileno方法的對象)。這些就是咱們等待的鏈接 3個序列用於輸入,輸出和異常狀況(錯誤和相似的東西) 若是沒有給定超時時間,select會阻塞(也就是處於等待狀態),直到其中一個文件描述符已經爲 行動作好了準備;若是給定了超時時間,select最多阻塞給定的超時時間,若是給定的超時時間是0, 那麼就給出一個連續的poll(即不阻塞)。select的返回值是3個序列(也就是一個長度爲3的元組), 沒個表明相應參數的一個活動子集。好比,返回的第一個序列是一個輸入文件描述符的序列,其中 有一些能夠讀取的東西 ''' import socket,select s=socket.socket() host=socket.gethostname() port=1234 s.bind((host,port)) s.listen(5) inputs=[s] while True: rs,ws,es=select.select(inputs,[],[]) for r in rs: if r is s: c,addr=s.accept() print('from',addr) inputs.append(c) #c.send(b'thank') for w in ws: if w: w.send(b'thanks') else: try: data=r.recv(1024) disconnect=not data except socket.error: disconnect=True if disconnect: print(r.getpeername(),'disconnect') inputs.remove(r) else: print(data.decode())
poll_test.py框架
#poll_test ''' 在調用poll時,會獲得一個poll對象。而後就可使用poll對象的register方法註冊一個文件描述符( 或使用帶有fileno方法的對象)。註冊後能夠unregister方法移除註冊的對象 註冊了一些對象(好比套接字)之後,就能夠調用poll方法(帶有一個可選的超時時間參數)並 獲得一個(fd,event)格式列表(多是空的),其中fd是文件描述符,event告訴你發生了什麼。 這是一個位掩碼,意思是它是一個整數,這個整數的每一個位對應不一樣的事件。 那些不一樣的事件是select模塊的常量。爲了驗證是否設置了一個給定位(也就是說,一個給定的事件 是否發生了),可使用按位與操做符: if event & select.POLLIN:... ''' import socket,select s=socket.socket() host=socket.gethostname() port=1234 s.bind((host,port)) fdmap={s.fileno():s} s.listen(5) p=select.poll() p.register(s) while True: events=p.poll() for fd,event in events: if fd=s.fileno(): c,addr=s.accept() print('from',addr) p.register(c) fdmap[c.fileno]=c elif event & select.POLLIN: data=fdmap[fd].recv(1024) if not data: print(fdmap[fd].getpeername(),'disconnect') p.unregister(fd) del fdmap[fd] else: print(data)
twisted_test.pysocket
#twisted ''' 以前編寫的基本套接字服務器是顯示的。其中的一些有很清楚的事件循環,來查找新的鏈接和新數據, 而基於socketserver的服務器有一個隱式循環,在循環中服務器查找鏈接併爲每一個鏈接建立一個處理程序, 但處理程序在要讀數據時必須是顯式的 Twisted使用一個事件甚至多個基於事件的方法。要編寫基本的服務器,就要實現處理好比 新客戶鏈接,新數據到達以及一個客戶端斷開鏈接等事件的事件處理程序 事件處理程序在一個協議(protocol)中定義,在一個新的鏈接到達時,一樣須要一個建立這種協議對象 的工廠(factory),但若是隻是想要建立一個通用的協議類的實例,那麼就可使用twisted自帶的工廠 當編寫本身的協議時,要使用和超類同樣的模塊中的protocol。獲得了一個鏈接後,時間處理程序connectionMade 就會被調用。丟失了一個鏈接後,connectionLost就會被調用。來自客戶端的數據是經過處理程序 dataReceived接收的。固然不能使用事件處理策略來把數據發回到客戶端,若是要實現此功能,能夠 使用對象self.transport的write方法,也有一個包含客戶機地址的client屬性 ''' from twisted.internet import reactor from twisted.internet.protocol import Protocol,Factory class SimpleLogger(Protocol): def connectionMade(self): print('from',self.transport.client) self.transport.write(b'thanks') def connectionLost(self,reason): print(self.transport.client,'disconnected') def dataReceived(self,data): print(data.decode()) factory=Factory() factory.protocol=SimpleLogger reactor.listenTCP(1234,factory) reactor.run()
twisted_LineReceiver.pyasync
#twisted LineReceiver協議 from twisted.internet import reactor from twisted.internet.protocol import Factory from twisted.protocols.basic import LineReceiver class SimpleLogger(LineReceiver): def connectionMade(self): print('from',self.transport.client) #self.transport.write(b'thanks') self.sendLine(b'thanks2') def connectionLost(self,reason): print(self.transport.client,'disconnected') def lineReceived(self,line): #客戶端發送的數據要加\r\n print(line.decode()) factory=Factory() factory.protocol=SimpleLogger reactor.listenTCP(1234,factory) reactor.run()