1. 程式人生 > >python socket 套接字編程 單進程服務器 實現多客戶端訪問

python socket 套接字編程 單進程服務器 實現多客戶端訪問

host port list 不能 ioerror 存儲 utf8 所有 tin

服務器:

 1 import socket
 2 #單進程服務器 實現多客戶端訪問 IO復用
 3 #吧所有的客戶端套接字 放在一個列表裏面,一次又一次的便利過濾
 4 #這就是apache: select模型 6 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 7 server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #設置端口復用
 8 #AF_INET: IPV4
 9 #AF_INET6: IPV6
10 #SOCK_STREAM: TCP
11 #SOCK_DGRAM: UDP
12 Host = ‘‘ 13 port = 23333 14 server.bind((Host,port)) 15 #服務器綁定端口 8080 16 server.listen(5) 17 #服務器同時監聽5個 最大鏈接數 5 18 19 print([+] server open) 20 21 c_server = {} 22 #定義一個全局字典 23 server.setblocking(0) 24 #設置服務器recv接受信息和send發送信息為非阻塞狀態(默認為阻塞狀態) 25 #是否阻塞(默認True),如果設置False,那麽accept和recv時一旦無數據,則報錯。 26
while True: 27 try: 28 try: 29 30 client,c_addr = server.accept() 31 32 except BlockingIOError: 33 #無法立即完成一個非阻止性套接字操作。 34 if not c_server: 35 #如果字典為空 36 continue 37 #重新接收套接字 38 pass 39
else: 40 client.setblocking(0)#設置套接字屬性為非阻塞 41 #是否阻塞(默認True),如果設置False,那麽accept和recv時一旦無數據,則報錯。 42 #[WinError 10035] 無法立即完成一個非阻止性套接字操作。 43 c_server[client] = c_addr#以字典形式存儲新鏈接的套接字 44 print([+] from,c_addr) 45 for a in list(c_server.keys()): 46 #這裏將字典的keys取出來 在列表化,在沒有信息的時候刪除套接字了 47 try: 48 msg = a.recv(1024).decode(utf-8) 49 #非阻塞接受消息,但是如果客戶端不馬上發送,就會報錯,所以設置一個延遲接收 50 except BlockingIOError as e: 51 continue 52 53 if not msg: 54 print([%s] closed%(c_server[a][0])) 55 a.close() 56 del c_server[a] 57 continue 58 print("來自%s的消息: %s"%(c_server[a][0],msg)) 59 a.send(msg.encode(utf-8)) 60 #發送重復的消息 61 except KeyboardInterrupt: 62 break 63 64 65 server.close()

客戶端:

 1 #coding:utf-8
 2 
 3 import socket
 4 client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 5 #創建一個客戶端鏈接,socket.AF_INET代表ipv4,socket.SOCK_STREAM代表tcp套接字
 6 client.connect((127.0.0.1,23333))
 7 #客戶端鏈接
 8 print([+]  鏈接成功)
 9 #鏈接成功顯示
10 while True:
11     msg = input(>>>)
12     if msg == quit:
13         #如果輸入的信息是quit  就退出鏈接
14         break
15     if len(msg) == 0:#如果直接輸入的一個回車的話
16     #就重新輸入,因為不能發送空 ,發送空的花  客戶端會卡住
17         continue
18     client.send(msg.encode(utf-8))
19     #客戶端發送信息msg  以utf8格式發送數據
20     data = client.recv(1024).decode(utf-8)
21     if not data:
22         #如果數據為空/0  
23         #服務器主動斷開s
24         break
25         print([+]  服務器主動斷開了鏈接......)
26 
27     print(服務器發來:,data)
28 
29 
30 print([+]  鏈接關閉...)
31 
32 client.close()

服務器就是apache: select模型

python socket 套接字編程 單進程服務器 實現多客戶端訪問