
正文
第四十一天 socker server和 event
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
今日内容
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 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
# 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 socketc = 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()






