Python網路程式設計---實現聊天室
阿新 • • 發佈:2018-12-15
寫一個聊天室
要求:
1.進入聊天室需要輸入姓名,姓名不能重複
2.有人進入聊天室會想其他人傳送通知,xxx 進入了聊天室
3.一個人發訊息,其他人會收到訊息
xxx 說:xxxx
4.某人退出聊天室,其他人也會收到通知
xxx 退出了聊天室
5.管理員喊話功能
-基於udp的網路傳輸
- 服務端:
#!/usr/bin/env python3
#coding=utf-8
'''
name:xx
email:xxx
data:2018/9/11
introduce:Chatroom server
env:python3.5
'''
from socket import *
import os,sys
#登入判斷
def do_login(s,user,name,addr):
if (name in user) or name == '管理員':
s.sendto('\n該使用者已存在'.encode(),addr)
return
s.sendto(b'OK',addr)
#通知其他人
msg='\n歡迎%s進入聊天室' % name
for i in user:
s.sendto(msg.encode(),user[i])
#插入使用者
user[name] = addr
#訊息傳送
def do_chat(s,user,name,text):
msg = '\n%s說:%s' % (name,text)
for i in user:
if i !=name:
#退出聊天室
def do_quit(s,user,name):
msg = '\n' +name + '退出了聊天室'
for i in user:
if i == name:
s.sendto(b'EXIT',user[i])
else:
s.sendto(msg.encode(),user[i])
#從字典中刪除使用者
del user[name]
#接收客戶端請求
def do_parent(s):
#儲存結構,{'zhangsan':('127.0.0.1',9999)}
user = {}
while True:
msg,addr = s.recvfrom(1024)
msgList = msg.decode().split(' ')
#區分請求型別
if msgList[0] == 'L':
do_login(s,user,msgList[1],addr)
elif msgList[0] == 'C':
do_chat(s,user,msgList[1],' '.join(msgList[2:]))
elif msgList[0] == 'Q':
do_quit(s,user,msgList[1])
#做管理員喊話
def do_child(s,addr):
while True:
msg = input('管理員訊息:')
msg = 'C 管理員 ' + msg
s.sendto(msg.encode(),addr)
#建立網路,建立程序,呼叫功能函式
def main():
#定義server address
ADDR = ('0.0.0.0',8888)
#建立套接字
s = socket(AF_INET,SOCK_DGRAM)
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(ADDR)
#建立一個單獨的程序處理管理員喊話功能
pid = os.fork()
if pid < 0:
sys.exit('建立程序失敗')
elif pid == 0:
do_child(s,ADDR)
else:
do_parent(s)
if __name__ == '__main__':
main()
- 客戶端
from socket import *
import os,sys
#傳送訊息
def send_msg(s,name,addr):
while True:
text = input('發言:')
#如果輸入quit表示退出
if text.strip() == 'quit':
msg = 'Q ' + name
s.sendto(msg.encode(),addr)
sys.exit('退出聊天室')
msg = 'C %s %s' % (name,text)
s.sendto(msg.encode(),addr)
#接收訊息
def recv_msg(s):
while True:
data,addr = s.recvfrom(2048)
if data.decode() == 'EXIT':
sys.exit(0)
print(data.decode() + '\n發言:',end='')
#建立套接字,登入,如果登入成功,建立子程序
def main():
#從命令列獲取服務端地址
if len(sys.argv) < 3:
print('argv is error')
return
HOST = sys.argv[1]
PORT = int(sys.argv[2])
ADDR = (HOST,PORT)
#建立套接字
s = socket(AF_INET,SOCK_DGRAM)
while True:
name = input('請輸入姓名:')
msg = 'L ' + name
#傳送登入請求
s.sendto(msg.encode(),ADDR)
#等待伺服器回覆
data,addr = s.recvfrom(1024)
if data.decode() == 'OK':
print('您已進入聊天室')
break
else:
#不成功伺服器會回覆不允許登入的原因
print(data.decode())
#建立父子程序
pid = os.fork()
if pid < 0:
sys.exit('建立子程序失敗')
elif pid == 0:
send_msg(s,name,ADDR)
else:
recv_msg(s)
if __name__ == '__main__':
main()
總結:
1、聊天室通過服務端轉發訊息給所有客戶端來實現群聊的功能。
2、採用基於udp的網路傳輸來完成。
3、採用多程序程式設計,父子程序分別處理訊息的接收和傳送