今天咱們的任務是基於python打造一個多人聊天室。python
聊天室的設計思想是 :在局域網下, 利用socket進行鏈接通訊,當服務器端啓動的時候,利用Thread線程不停的等待客戶端的連接;當有客戶端開啓連服務器
接的時候,服務器端經過IO流反饋「上線用戶」信息給客戶端,客戶端也使用線程不停的接收服務器的信息,從而實現多人在線聊天功能。多線程
1.編寫服務器端程序:socket
1 # -*-coding:utf-8-*- 2 3 #服務端 4 5 import socket 6 import threading 7 8 def clientThreadIn(conn,nick): 9 global data 10 while True: 11 try: 12 temp = conn.recv(1024)#客戶端發過來的消息 13 if not temp: 14 conn.close() 15 return 16 NotifyAll(temp) 17 print data 18 19 except: 20 NotifyAll(nick+'leaves the room')#出現異常就退出 21 print data 22 return 23 24 def clientThreadOut(conn,nick): 25 global data 26 while True: 27 if con.acquire(): 28 con.wait()#堵塞,放棄對資源的佔有 等待通知運行後面的代碼 29 if data: 30 try: 31 conn.send(data) 32 con.release() 33 except: 34 con.release 35 return 36 37 38 def NotifyAll(ss): 39 global data 40 if con.acquire():#獲取鎖 41 data = ss 42 con.notifyAll()#當前線程放棄對資源的佔有,通知全部等待x線程 43 con.release() 44 45 46 con = threading.Condition()#條件 47 Host = raw_input('input the server ip address:')# ip地址 48 port = 1111 49 data = '' 50 51 52 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#建立套接字 53 print 'Socket created' 54 s.bind((Host,port)) #把套接字綁定到ip地址 55 s.listen(5) 56 print 'Socket now listening' 57 58 while True: 59 conn,addr = s.accept()#接受鏈接 60 print 'Connected with'+'' +addr[0]+':'+str(addr[1]) #字符串拼接 61 nick = conn.recv(1024)#獲取用戶名 62 NotifyAll('Welcome'+' '+nick+' to the room!') 63 print data 64 print str((threading.activeCount()+1)/2)+'person(s)' 65 conn.sendall(data) 66 threading.Thread(target=clientThreadIn,args=(conn,nick)).start() 67 threading.Thread(target=clientThreadOut,args=(conn,nick)).start()
2.編寫客戶端程序:函數
1 # -*-coding:utf-8-*- 2 3 #socket 服務端和客戶端 服務端監聽 客戶端的請求 連接確認 4 5 import socket 6 import threading 7 8 outString = '' 9 inString = '' 10 nick = '' 11 12 #發送信息的函數 13 def DealOut(sock): 14 global nick,outString #聲明爲全局變量,進行賦值,這樣才能夠生效 15 while True: 16 outString = raw_input() #輸入 17 outString = nick+':'+outString#拼接cd 18 sock.send(outString)#發送 19 20 #接收信息 21 def DealIn(sock): 22 global inString 23 while True: 24 try: 25 inString = sock.recv(1024) 26 if not inString: 27 break 28 if outString != inString: 29 print inString 30 except: 31 break 32 33 34 35 nick = raw_input('input your nickname:')#名字 36 ip = raw_input('input your server ip address:')#ip地址 37 38 39 sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#建立套接字,默認爲ipv4 40 sock.connect((ip,1111)) #發起請求,接收的是一個元組 41 sock.send(nick) 42 43 #多線程 接收信息 發送信息 44 thin = threading.Thread(target=DealIn,args=(sock,))#調用threading 建立一個接收信息的線程' 45 thin.start() 46 47 thout = threading.Thread(target=DealOut,args=(sock,))# 建立一個發送信息的線程,聲明是一個元組 48 thout.start()
3.最後貼一張效果圖ui