multi_socket

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()
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息