Python_模拟多人聊天室

服务端

from socket import *
import os

# 绑定服务端地址
ADDR = ("127.0.0.1", 8888)
# 临时存储用户信息
user = {}

# 登录请求处理
def login(s, name, addr):
	# 判断是否同名
    if name in user or "管理" in name:
    	# 进入失败返回FAIL
        s.sendto(b"FAIL", addr)
        return
    else:
    	# 进入成功返回OK
        s.sendto(b"OK", addr)
    # 广播消息
    msg = "\n欢迎 %s 进入聊天室" % name
    for i in user:
        s.sendto(msg.encode(), user[i])
    # 记录客户端信息
    user[name] = addr

# 处理聊天请求
def transfer(s, name, msg_content):
	# 转发消息
    msg = "\n%s:%s" % (name, msg_content)
    for i in user:
        if i != name:
            s.sendto(msg.encode(), user[i])

# 处理退出请求
def 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 manager_message(s):
    while True:
        content = input(">>>")
        msg = "CHAT 管理员消息 %s" % content
        s.sendto(msg.encode(), ADDR)

# 主函数
def main():
	# 创建UDP套接字
    s = socket(AF_INET, SOCK_DGRAM)
    # 绑定服务端地址
    s.bind(ADDR)
    # 创建多进程
    pid = os.fork()
    if pid < 0:
        print("Error")
    # 子进程,用于发送管理员消息
    elif pid == 0:
        manager_message(s)
    # 父进程,用于处理客户端请求
    else:
        while True:
        	# data提前约定通信协议
            data, addr = s.recvfrom(1024)
            # 解析请求
            tmp = data.decode().split(" ", 2)
            # 连接请求
            if tmp[0] == "CONNECT":
                login(s, tmp[1], addr)
            # 聊天请求
            elif tmp[0] == "CHAT":
                transfer(s, tmp[1], tmp[2])
            # 退出请求
            elif tmp[0] == "QUIT":
                quit(s, tmp[1])


if __name__ == "__main__":
    main()

客户端

from socket import *
import os, sys

# 记录服务端地址
ADDR = ("127.0.0.1", 8888)


# 主函数
def main():
	# 创建UDP套接字
    s = socket(AF_INET, SOCK_DGRAM)
    while True:
        name = input("请输入姓名:")
        # 根据通信协议组织进入消息
        msg = "CONNECT %s" % name
        s.sendto(msg.encode(), ADDR)
        feedback, addr = s.recvfrom(1024)
        # 收到OK,进入聊天室成功
        if feedback == b"OK":
            print("您已进入聊天室")
            break
        else:
        	# 收到FAIL,进入聊天室失败
            print("该用户已存在")
	
	# 创建多进程
    pid = os.fork()
    if pid < 0:
        print("Error!")
        return
    # 子进程,用于发送消息
    elif pid == 0:
        while True:
        	# 捕获客户端退出并处理
            try:
            	# 输入quit也可退出
                content = input(">>>")
            except:
                content = "quit"
            if content == "quit":
            	# 根据通信协议组织退出消息
                msg = "QUIT %s" % name
                s.sendto(msg.encode(), ADDR)
                sys.exit("您已退出群聊")
            else:
            	# 根据通信协议组织聊天消息
                msg_send = "CHAT %s %s" % (name, content)
                s.sendto(msg_send.encode(), ADDR)
    # 父进程,用于收消息
    else:
        while True:
            data, addr = s.recvfrom(1024)
            # 如收到EXIT代码,说明“发”进程已退出并传递了信号到“收”进程
            if data == b"EXIT":
                sys.exit()
            # 消息展示
            print(data.decode() + "\n>>>", end="")


if __name__ == "__main__":
    main()

你可能感兴趣的:(tiny_project)