UDP多人聊天室

#多人聊天室

"""
chat room
客户端
功能: 发送请求, 获取结果
"""

from socket import *
from multiprocessing import Process
import sys

# 服务器地址
ADDR = ('127.0.0.1',8888)

# 接收消息
def recv_msg(s):
    while True:
        data,addr = s.recvfrom(4096)
        print(data.decode() + "\n发言:",end="")  # 打印接收内容

# 发送消息
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 main():
    s = socket(AF_INET,SOCK_DGRAM)
    # 进入聊天室
    while True:
        name = input("请输入姓名:")
        msg = "L "+name  # 根据协议,组织消息格式
        s.sendto(msg.encode(),ADDR) # 将姓名发送给服务端
        data,addr = s.recvfrom(128) # 接收反馈
        if data.decode() == 'OK':
            print("您已进入聊天室")
            break
        else:
            print(data.decode())

    # 创建一个新的进程
    p = Process(target = recv_msg,args=(s,))  # 子进程接收消息
    p.daemon = True # 子进程随父进程退出
    p.start()
    # 发送消息
    send_msg(s,name)  # 发送消息由父进程执行




if __name__ == '__main__':
    main()

"""
chat room
env: python3.6
socket udp  and process
"""

from socket import *
from multiprocessing import Process

# 服务器地址
HOST = "0.0.0.0"
PORT = 8888
ADDR = (HOST,PORT)

# 用户信息存储  {name : address}
user = {}

# 处理进入聊天室
def do_login(s,name,address):
    if name in user or "管理" in name:
        s.sendto("该用名已经存在".encode(),address)
        return
    else:
        s.sendto(b'OK', address)
        # 告知其他人
        msg = "\n欢迎 %s 进入聊天室" % name
        for i in user:
            s.sendto(msg.encode(),user[i])
        user[name] = address # 字典中增加一项

# 处理聊天
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):
    del user[name] # 删除用户
    msg = "\n%s 退出聊天室"%name
    for i in user:
        s.sendto(msg.encode(),user[i])

# 接收各个客户端请求
def request(s):
    """
    总分模式
    1. 接收不同的客户端请求类型
    2. 分情况讨论
    3. 不同的情况调用 不同的封装方法
    4. 每个封装功能设计参考 学的函数或者类的设计过程
    """
    while True:
        data,addr = s.recvfrom(1024)  # 接收请求
        tmp = data.decode().split(' ',2) # 对请求解析
        if tmp[0] == 'L':
            # 处理进入聊天室 tmp --> ['L', 'name']
            do_login(s,tmp[1],addr)
        elif tmp[0] == 'C':
            # 处理聊天  tmp --> [C , name,xxxx]
            do_chat(s,tmp[1],tmp[2])
        elif tmp[0] == 'Q':
            # 处理退出 tmp --> [Q,  name]
            do_quit(s,tmp[1])

# 发送管理员消息
def manager(s):
    while True:
        msg = input("管理员消息:")
        msg = "C 管理员 "+ msg
        s.sendto(msg.encode(), ADDR)  # 从父进程将消息发送给子进程

# 搭建基本结构
def main():
    # 创建一个udp套接字
    s = socket(AF_INET,SOCK_DGRAM)
    s.bind(ADDR)

    # 创建新的进程用于给客户端发送管理员消息
    p = Process(target = request,args=(s,))
    p.start()

    manager(s)  # 处理发来的请求

    p.join()

if __name__ == '__main__':
    main()


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值