import socket
import select
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(("127.0.0.1", 9999))
server.setblocking(False)
server.listen(9)
recv_list = [server, ]
while True:
r, w, e = select.select(recv_list, [], [], 0.5)
for item in r:
if item == server:
conn, addr = server.accept()
print("有人连接", addr)
recv_list.append(conn)
else:
data = item.recv(1024)
if data:
print("收到信息", data.decode("utf-8"))
item.close()
recv_list.remove(item)
else:
print("客户端已关闭连接")
recv_list.remove(item)
import socket
import select
client_list = []
for i in range(5):
client = socket.socket()
client.setblocking(False)
try:
client.connect(("127.0.0.1", 9999))
except BlockingIOError as e:
pass
except ConnectionRefusedError as e:
print("第{}次连接失败".format(i + 1), e)
client_list.append(client)
recv_list = []
while True:
r, w, e = select.select(recv_list, client_list, [], 0.1)
for item in w:
item.sendall("在吗".encode("utf-8"))
recv_list.append(item)
client_list.remove(item)
for item in r:
reply = item.recv(1024)
if reply:
print(reply.decode("utf-8"))
recv_list.remove(item)
item.close()
else:
print("服务端已关闭连接")
recv_list.remove(item)
D:\anaconda3\python.exe D:/pycharm文件/io多路复用/客户端.py
服务端已关闭连接
第二行 和上面一样
第三行 这里同上 因为不让重复太多 只能这样写
服务端已关闭连接
服务端已关闭连接
Traceback (most recent call last):
File "D:\pycharm文件\io多路复用\客户端.py", line 23, in
r, w, e = select.select(recv_list, client_list, [], 0.1)
OSError: [WinError 10022] 提供了一个无效的参数。
进程已结束,退出代码1
把 服务端的 最底下的 # item.close() 给注释掉了 结果是
D:\anaconda3\python.exe D:/pycharm文件/io多路复用/客户端.py
服务端已关闭连接
第二行 和上面一样
第三行 这里同上 因为不让重复太多 只能这样写
服务端已关闭连接
然后这里时一直等待状态 服务端什么都没发送 为什么客户端接收到了 关闭链接的的信息?
没注释情况,服务端已经关掉了,客户端可读socket集合里面没有对应连接了,开启注释情况下,连接没有关闭,接收数据为none,所以打印五次!最后select相关集合为空了,所以会报10022那个错误
按照你现在的逻辑,如果item.close()不注释掉,那么当服务端收到消息,然后就把该连接关闭了,如果注释掉,客户端因为没有收到回复,所以也会进入到else的分支中,提示服务器已关闭,你现在主要的问题是服务器没有回复操作,你收到信息了得给客户端一个回应啊,这就像两人打电话,一个一直喂喂喂,另一个不始终不说话,那只能是认为断线了