server
# coding=utf-8
from socket import *
import os,sys
# 存储用户 {name:addr}
user = {}
#处理登录
def do_login(s,name,addr):
if (name in user) or ('管理员' in name):
s.sendto('该用户存在'.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,name,text):
msg = "\n%s : %s"%(name,text)
for i in user:
if i != name:
s.sendto(msg.encode(),user[i])
def do_quit(s,name):
msg = '\n%s 退出了聊天室'%name
for i in user:
if i != name:
s.sendto(msg.encode(),user[i])
else:
s.sendto(b'EXIT',user[i])
# 删除用户
del user[name]
# 处理客户端请求
def do_request(s):
while True:
# 接收所有客户端请求
data,addr = s.recvfrom(1024)
# print(data.decode()) # 请求内容
msgList = data.decode().split(' ')
#区分请求类型
if msgList[0] == 'L':
do_login(s,msgList[1],addr)
elif msgList[0] == 'C':
text = ' '.join(msgList[2:])
do_chat(s,msgList[1],text)
elif msgList[0] == 'Q':
do_quit(s,msgList[1])
# 搭建网络连接
def main():
ADDR = ('0.0.0.0',8888)
#创建udp套接字
s = socket(AF_INET,SOCK_DGRAM)
s.bind(ADDR)
# 创建单独进程用于发送管理员消息
pid = os.fork()
if pid < 0:
print("Create process failed")
return
elif pid == 0:
while True:
msg = input("管理员消息:")
msg = "C 管理员消息 " + msg
s.sendto(msg.encode(),ADDR)
else:
# 处理各种客户端请求
do_request(s)
main()
client
from socket import *
import os,sys
# 服务端地址
ADDR = ('127.0.0.0',8888)
def send_msg(s,name):
while True:
try:
text = input("发言:")
except KeyboardInterrupt:
text = 'quit'
# 输入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(1024)
if data.decode() == 'EXIT':
sys.exit()
print(data.decode()+'\n发言:',end='')
# 创建网络连接
def main():
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:
return
elif pid == 0:
send_msg(s,name)
else:
recv_msg(s)
main()