python3 利用socket和i/o多路複用實現簡易羣聊服務器

服務端

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()

客戶端需要多複製幾份運行

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章