python非阻塞式單程序伺服器
阿新 • • 發佈:2019-01-04
python的單程序伺服器一次只能處理一個客戶端,顯然是沒有實用價值的,但是我們可以將單程序伺服器變為非阻塞式的。
利用socket中的setblocking()方法可以將tcp套接字轉化為非阻塞式套接字,可處理多個客戶端,且不會相互影響,因為是非阻塞式的,但是要注意,轉化為非阻塞式之後,如果沒有接收到客戶端訊息則會產生異常,所以要用到異常處理,以及每次接收到的客戶端訊息不斷更新,需要使用列表進行儲存。
主要程式碼如下:
#-*- coding:utf-8 -*-
from socket import *
#建立套接字
serSocket = socket(AF_INET, SOCK_STREAM)
localAddr = ('' , 7789)
#為其繫結本機資訊
serSocket.bind(localAddr)
#將tcp套接字轉化為非阻塞式
serSocket.setblocking(False)
#將套接字變為被動監聽
serSocket.listen(5)
#用來儲存所有客戶端的資訊
clientAddrList = []
while True:
#print("---wait for client---")
try:
newSocket, clientAddr = serSocket.accept()
except:
pass
else:
print('---new client [%s]' %(str(clientAddr)))
#為了不令接收到的客戶端套接字陷入阻塞狀態,將客戶端套接字也轉為非阻塞
newSocket.setblocking(False)
clientAddrList.append((newSocket, clientAddr))
#因為引用計數器的關係,每一次迴圈的執行都會使newSocket變為新的物件,newSocket無法在接下來使用,應將其存在列表裡
for newSocket, clientAddr in clientAddrList:
try:
recvDate = newSocket.recv(1204 )
except:
pass
else:
if len(recvDate) > 0:
print('---massage from [%s] is: %s---'%(str(clientAddr), recvDate.decode('utf-8')))
else:
print('---client was closed---')
newSocket.close()
clientAddrList.remove((newSocket, clientAddr))