服务端
import socket
import select
# i/o复用实例,利用操作系统对i/o流的阻塞,单线程多人群聊服务器
ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss.bind(('127.0.0.1', 5985))
ss.listen(10)
readlist = [ss] # 读监听列表,ss是服务器连接
writelist = [] # 写监听列表
msg_content = "" # 用来存消息内容
print('服务器已启动')
while True:
# i/o复用监听,rlist读事件列表,wlist写事件列表,xlist错误列表,readlist所有读监听连接,rlist监听到的读事件连接
rlist, wlist, xlist = select.select(readlist, writelist, []) # select监听1024个,poll监听无限个,epoll无限个(Linux,web)
for r in rlist:
if r is ss: # 新的客户端连入执行
conn, addr = r.accept()
readlist.append(conn) # 把新的客户端加入读监听列表
else: # 客户端发消息执行
msg = r.recv(1024)
msg_content = str(r.fileno())+':'+msg.decode('utf-8')
if len(msg) == 0:
r.close()
readlist.remove(r) # 客户端无消息发送删除连接
for i in readlist: # 把除了ss服务器的,其余所有连接放入写列表
if i is not ss:
writelist.append(i)
for w in wlist:
msg_split = msg_content.split(":") # 分割字符串
w.send(("编号为{}说:{}".format(msg_split[0], msg_split[1])).encode('utf-8')) # 发送消息
writelist.remove(w) # 发送完删除写连接
客户端
import socket
import threading
c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c.connect(('127.0.0.1', 5985))
def recv_msg():
while True:
msg = c.recv(10000).decode('utf-8')
print(msg)
st = threading.Thread(target=recv_msg)
st.start()
def send_msg():
while True:
msg = input('输入消息:')
c.send(msg.encode('utf-8'))
if __name__ == '__main__':
send_msg()
客户端需要多复制几份运行