基於udp協議的群聊聊天室程式碼
今天用python寫了一個簡單的群聊程式,分享一下
#server.py
from socket import *
import os,sysdef do_login(s,user,name,addr):
if (name in user) or name == "管理員":
s.sendto("該使用者已存在".encode(),addr)
return
s.sendto('ok'.encode(),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%-4s 說:%s'%(name,text)
#發給除了自己以外的所有人
for i in user:
if i != name:
s.sendto(msg.encode(),user[i])
def do_quit(s,user,name):
del user[name]
msg = "\n" + name + '離開了聊天室'
for i in user:
s.sendto(msg.encode(),user[i])
#接受客戶端請求並處理
def do_child(s):
#使用者儲存使用者{'zhangsan':('172,168,50,36',7777)}
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:]))
else:
do_quit(s,user,msglist[1])
#傳送管理員訊息
def do_parent(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:
#建立二級子程序
pid0 = os.fork()
if pid0 < 0:
sys.exit("建立二級程序失敗")
elif pid0 == 0:
#執行子程序功能
do_child(s)
else:
os._exit(0)
else:
os.wait()
#執行父程序功能
do_parent(s,ADDR)
if __name__ == '__main__':
main()
#client.py
from socket import *
import os,sys
import signal
#傳送訊息
def do_child(s,name,addr):
while True:
text = input("發言(quit退出):")
if text.strip() == 'quit':
msg = 'Q ' + name
s.sendto(msg.encode(),addr)
#從子程序中殺死父程序
os.kill(os.getppid(),signal.SIGKILL)
sys.exit("退出聊天室")
else:
msg = 'C %s %s'%(name,text)
s.sendto(msg.encode(),addr)
#接受訊息
def do_parent(s):
while True:
msg,addr = s.recvfrom(1024)
print(msg.decode()+"\n發言(quit退出):",end='')
#建立套接字,建立父子程序,登入
def main():
if len(sys.argv) < 3:
print("")
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:
do_child(s,name,ADDR)
else:
do_parent(s)
if __name__ == '__main__':
main()