代碼:
用戶端:
#!/usr/bin/env python#coding:utf8 #python2.73 lession7_1_s.py"""這是一個多用戶端 用來測試 有5個使用者 7個訊息 一共發送35次 """import socketfrom time import sleepmsg = ['cs111','cs222','cs333','cs444','cs555','cs666','cs777']ss = [] #用戶端集合saddr = ('localhost',30001)for i in range(5): s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) ss.append(s)for s in ss: s.connect(saddr)counts = 0for m in msg: for s in ss: #向服務端發送資訊 s.send("client num: %s meg: %s"%(counts,m)) counts+=1 for s in ss: #從服務端獲得返回資訊 data = s.recv(1024) print "%s echo %s"%(s.getpeername(),data) if not data: s.close()
服務端:
#!/usr/bin/env python#coding:utf8 #python2.73 lession7_1_s.pyimport socketimport selectimport Queuesaddr = ('localhost',30001)sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)sock.setblocking(False) #設定socket是非阻塞的sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)sock.bind(saddr)#綁定地址sock.listen(10)#conn,addr = s.accept()rlists = [sock] #select參數 可寫狀態集合wlists = [] #select參數 可讀狀態集合msg_que = {}timeout = 20 #print 'connented with addr:',addr while rlists: rs,ws,es = select.select(rlists, wlists, rlists, timeout) if not (rs or ws or es): print 'timeout...' continue #大體思路就是對所有的返回組進行迴圈 查看狀態作出動作 for s in rs: if s is sock: #是否是服務端的sock conn,addr = s.accept() print 'connect by',addr conn.setblocking(False) rlists.append(conn) msg_que[conn] = Queue.Queue() else: #客戶段的sock接受資料 data = s.recv(1024) if data: print data msg_que[s].put(data) if s not in wlists: wlists.append(s) else: if s in wlists: wlists.remove(s) rlists.remove(s) s.close() del msg_que[s] for s in ws: try: msg = msg_que[s].get_nowait() except Queue.Empty: print 'msg empty' wlists.remove(s) else: s.send(msg) for s in es: print 'except ',s.getpeername() if s in rlists: rlists.remove(s) if s in wlists: wlists.remove(s) s.close() del msg_que[s]