1、服务端代码
from socket import *
import os, sys
# 服务器地址
ADDR = ('0.0.0.0', 8888)
# 存储用户信息
user = {}
# 进入聊天室
def do_login(s,name,addr):
if name in user or "管理员" in 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,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 = "%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)
msg = data.decode().split(' ')
# 区分请求类型
if msg[0] == 'L':
do_login(s,msg[1],addr)
elif msg[0] == 'C':
text = ' '.join(msg[2:])
do_chat(s,msg[1],text)
elif msg[0] == 'Q':
if msg[1] not in user:
s.sendto(b'EXIT',addr)
continue
do_quit(s,msg[1])
# 创建网络连接
def main():
# 套接字
s = socket(AF_INET, SOCK_DGRAM)
s.bind(ADDR)
pid = os.fork()
if pid < 0:
return
# 发送管理员消息
elif pid == 0:
while True:
msg = input("管理员消息:")
msg = "C 管理员消息 " + msg
s.sendto(msg.encode(),ADDR)
else:
# 请求处理
do_request(s) # 处理客户端请求
if __name__ == '__main__':
main()
2、客户端代码
from socket import *
import os,sys
# 服务器地址
ADDR = ('172.40.91.188',8888)
# 发送消息
def send_msg(s,name):
while True:
try:
text = input("发言:")
except KeyboardInterrupt:
text = 'quit'
# 退出聊天室
if text == '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)
# 服务端发送EXIT表示让客户端退出
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:
sys.exit("Error!")
elif pid == 0:
send_msg(s,name)
else:
recv_msg(s)
if __name__ == "__main__":
main()