第四十一天 socker server和 event
阿新 • • 發佈:2018-11-16
今日內容
1.基於TCP的socketserver
2.基於UDP的socketserver
3.event
一.TCP的socketserver
#伺服器 import socketserver from threading import current_thread # fork linux下一個多程序介面 windows沒有這介面 # 用於處理請求的類 class MyHandler(socketserver.BaseRequestHandler): def handle(self): print(self) print(self.server) #獲取封裝的伺服器物件 print(self.client_address)# 客戶端地址 print(self.request)# 獲取客戶端的socket物件 print(current_thread()) while True: data = self.request.recv(1024) print(data.decode("utf-8")) self.request.send(data.upper()) server = socketserver.ThreadingTCPServer(("127.0.0.1",9999),MyHandler) server.serve_forever()
#客戶端
import socket
c = socket.socket()
c.connect(("127.0.0.1",9999))
while True:
msg = input(">>>:")
c.send(msg.encode("utf-8"))
print(c.recv(1024).decode("utf-8"))
二.基於UDP的socketserver
# 伺服器 import socketserverfrom threading import current_thread # fork linux下一個多程序介面 windows沒有這介面 # 用於處理請求的類 class MyHandler(socketserver.BaseRequestHandler): def handle(self): print(self) print(self.server) # 獲取封裝的伺服器物件 print(self.client_address)# 客戶端地址 print(self.request)# 是一個元祖 包含收到的資料 和伺服器端的socket # data,client = self.request data = self.request[0] print(data.decode("utf-8")) self.request[1].sendto(b"i am server",self.client_address) server = socketserver.ThreadingUDPServer(("127.0.0.1",9999),MyHandler) server.serve_forever() # ThreadingUDPServer 在初始化的時候建立了socket物件 # serve_forever() 將sockt註冊到select(多路複用的) # select中返回一個ready 如果為True則可以處理 _handle_request_noblock 內部建立了一個MyHandler的示例 呼叫了handler函式 # 使用了socket OOP 多執行緒 # 正常開發中 如果併發量不大 就是用socketserver # 否則用協程 """ 使用時的區別: ThreadingTCPServer handler 在連線成功時執行 self.request 是客戶端的socket物件 ThreadingUDPServer handler 接收到資料時執行 self.request 資料和伺服器端的socket物件 """ # 客戶端 import socket c = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) addr = ("127.0.0.1",9999) while True: msg = input(">>>:") c.sendto(msg.encode("utf-8"),addr) print(c.recvfrom(1024)[0].decode("utf-8"))
三.Event
"""
事件是什麼?
某件事情發生的訊號
用來幹什麼?
線上程間通訊 然而執行緒本來就能通訊
作用只有一個就是簡化程式碼
執行緒間通訊的例子
伺服器啟動需要五秒
客戶端啟動後去連線伺服器
去連線伺服器必須保證伺服器已經開啟成功了
是否啟動完成就是要通訊的內容
注意 Event執行緒通訊 僅僅用於簡單的條件判斷 說白了代替bool型別 和if判斷
set() 將狀態修改為True
wati() 等待狀態為True才繼續執行
"""
# import time # from threading import Thread # boot = False # def server_task(): # global boot # print("正在啟動....") # time.sleep(5) # print("啟動....成功") # boot = True # # def client_task(): # while True: # print("連線伺服器....") # time.sleep(1) # if boot: # print("連線成功") # break # else: # print("error 連線失敗 伺服器未啟動!!") # # t1 = Thread(target=server_task) # t1.start() # # t2 = Thread(target=client_task) # t2.start() # # t1.join() # t2.join() # 使用事件實現 import time from threading import Thread,Event event =Event() def server_task(): print("正在啟動....") time.sleep(5) print("啟動....成功") event.set() def client_task(): event.wait() #一個阻塞的函式 會阻塞直到對event執行set函式為止 print("連線成功!") t1 = Thread(target=server_task) t1.start() t2 = Thread(target=client_task) t2.start()