服務端
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()
客戶端需要多複製幾份運行