import socket
import time
server=socket.socket()
print(server)
server.setblocking(False)
server.bind((“”,3333))
server.listen(5)
print(server)
print(“开始监听”)
con_list=[]
while True:
try:
con,adr=server.accept()
con.setblocking(False)
except BlockingIOError as e:
pass
else:
print(“客户端{},建立连接”.format(adr))
con_list.append(con)
for con in con_list:
try:
data=con.recv(1024)
except BlockingIOError as e:
pass
else:
print(data)
try:
msg=input(“>>>”)
con.send(msg.encode())
except BlockingIOError as e:
print(e)
客户端
import socket
import time
c = socket.socket()
c.setblocking(False)
try:
c.connect((“127.0.0.1”,3333))
except BlockingIOError as e:
pass
else:
print(“连接成功”)
while True:
msg=input(“<<<”)
try:
c.send(msg.encode())
except BlockingIOError as e:
pass
else:
try:
data=c.recv(1024)
except BlockingIOError as e:
print(e)
else:
print(data)
setblocking(False) 服务端server设置为非阻塞,conn设置为非阻塞,客户端 c设置为非阻塞。
设置非阻塞后,accept、recv、send、c.connect()都会报BlockingIOError, 所以要try包围。
现在的模式:服务端只有在接收到客户端的信息后才能回复信息,客户端可以只有先发了信息后才能收到信息。
非阻塞套接字的缺点:
关键一: 任何Python操作都是需要花费CPU资源的 !
关键二: 如果资源还没有到达,那么
accept、recv以及
send(在connect没有完成时)
操作都是无效的CPU花费 !
关键三: 对应BlockingIOError的异常处理
也是无效的CPU花费 !
IO多路复用
我们把socket交给操作系统来监控收发信息。
epoll 是惰性的
事件回调
惰性事件回调是由用户进程自己调用的。
操作系统只起到通知的作用。
epoll,目前是linux上效率最高的IO多路复用
IO多路复用选择器:
import socket
import selectors
import time
#sel=selectors.EpollSelector();#选择epoll linux的
sel=selectors.DefaultSelector();#默认选择器 根据操作系统变换
server=socket.socket()
server.bind((‘’,8888))
server.listen(5)
print(“开始监听”)
def readable(conn):
data=conn.recv(1024)
if data:
print(data)
else:
sel.unregister(conn)
conn.close()
def acc(server):
conn,addr = server.accept()
print(‘客户端{},连接成功’.format(addr))
sel.register(conn,selectors.EVENT_READ,readable)
#注册事件
sel.register(server,selectors.EVENT_READ,acc)
while True:
events = sel.select()#返回变化的套接字
for key,mask in events:
print(key)# 第一次打印haha SelectorKey(fileobj=<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=(‘0.0.0.0’, 4444)>, fd=4, events=1, data=<function acc at 0x7fc271f77c80>)
#有数据交互:haha SelectorKey(fileobj=<socket.socket fd=5, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=(‘127.0.0.1’, 4444), raddr=(‘127.0.0.1’, 54658)>, fd=5, events=1, data=<function readable at 0x7fc27347b2f0>)
time.sleep(5)
callback = key.data
callback(key.fileobj)
-
第一步:import selectors
-
第二步:sel=selectors.EpollSelector();#选择epoll 是linux的。
sel=selectors.DefaultSelector();#默认选择器 根据操作系统变换
- 第三步:注册事件 sel.register(server,selectors.EVENT_READ,acc)。
第一个参数是套接字,第二个参数是可读,第三个参数是一个回调函数。 - 第四步:events = sel.select() 遍历events
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
0WdrLA-1714955709304)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!