zoukankan      html  css  js  c++  java
  • udp协议与进程结合(群聊)

    服务端:

    """
    /etc/python3
    @File     : chat_server.py
    @Time     : 2020/7/13 下午5:15
    @Author   : wangyongqi
    @Email    : 92644827@qq.com
    @SOftware : PyCharm
    """
    from socket import *
    from multiprocessing import Process
    
    # 服务器使用地址
    HOST = "0.0.0.0"
    PORT = 8848
    ADDR = (HOST,PORT)
    
    # 存储用户 {name:address ...}
    user = {}
    
    # 处理进入聊天室
    def do_login(sock,name,address):
        if name in user or '管理' in name:
            sock.sendto(b"FAIL",address)
            return
        else:
            sock.sendto(b"OK", address)
            # 通知其他人
            msg = "欢迎 %s 进入聊天室"%name
            for i in user:
                sock.sendto(msg.encode(),user[i])
            # 存储用户
            user[name] = address
            # print(user)
    
    def get(sock,name,top):
            tmp='%s:%s'%(name,top)
            print(tmp)
            for i in user:
                if i!=name:
                    sock.sendto(tmp.encode(),user[i])
    
    def delect_exit(sock,name):
        del user[name]
        for i in user:
            sock.sendto(f'{name}退出了聊天'.encode(), user[i])
    
    
    #将处理事件放在子进程,因为父进程要接收和处理管理员消息
    def handle(sock):
        # 循环接收来自客户端请求
        while True:
            # 接收请求 (所有用户的所有请求)
            data, addr = sock.recvfrom(1024)
            tmp = data.decode().split(' ', 2)  # 对请求内容进行解析
            # 根据请求调用不同该函数处理
            if tmp[0] == 'L':
                # tmp ==> [L,name]
                do_login(sock, tmp[1], addr)  # 处理用户进入聊天具体事件
            #如果标记为C 则是消息进行转发
            elif tmp[0] == 'C':
                get(sock, tmp[1], tmp[2])
            #如果表记是e就是退出的表记
            elif tmp[0] == 'e':
                delect_exit(sock, tmp[1])
    
    
    # 启动函数
    def main():
        sock = socket(AF_INET,SOCK_DGRAM)  # UDP套接字
        sock.bind(ADDR)
        #设置消息处理的子进程
        p=Process(target=handle,args=(sock,))
        #子进程随着父进程的结束而退出<避免出现孤儿进程的情况>
        p.daemon=True
        #启动子进程
        p.start()
        #循环接收管理员消息(父进程的消息<输入的消息>)
        while True:
            conment=input("管理员:")
            #如果管理员输入exit也就是退出直接跳出循环结束父进程<子进程随之结束>
            if conment=='exit':
                break
            #若程序未跳出就将消息加标记 发给自己,然后处理转发给everyone
            data=f'c 管理员 {conment}'
            sock.sendto(data.encode(),ADDR)
    
    
    if __name__ == '__main__':
        main()

    客户端:

    """
    /etc/python3
    @File     : chat client.py
    @Time     : 2020/7/13 下午5:15
    @Author   : wangyongqi
    @Email    : 92644827@qq.com
    @SOftware : PyCharm
    """
    from socket import *
    from  multiprocessing import *
    
    # 服务端地址
    ADDR = ("127.0.0.1",8848)
    
    # 请求进入聊天室 OK FAIL
    def login(sock):
        while True:
            name = input("Name:")
            #加请求登录的表记L和用户名
            msg = "L " + name  # 根据通信协议整理发送信息
            print(name)
            #向服务器进行发送请求,服务器根据表记进行相应的处理
            sock.sendto(msg.encode(),ADDR) # 发送请求
            #等待服务器返回是否同意登录的应答
            result,addr = sock.recvfrom(128) # 等待回复
            #服务器返回OK说明登陆成功可以进行后续处理
            if result.decode() == 'OK':
                #主动给出提示
                print("您已进入聊天室")
                #返回用户名待用
                return name
            else:
                print("你的名字太受欢迎了,换一个吧")
    
    
    #向服务器发送消息
    def put(sock,name):
        while True:
            msg=input('说:')
            #判定消息如果退出结束父进程
            if msg=='exit':
                data = "e %s"%(name)
                sock.sendto(data.encode(), ADDR)  # 发送内容
                break
            #输入普通消息则加标记发送给服务器进行转发
            else:
                data = "C %s %s"%(name,msg) #C为普通消息
                sock.sendto(data.encode(),ADDR)  # 发送内容
    
    
    
    
    def get(sock):
        while True:
            #阻塞等待服务器转发的消息
            data,addr = sock.recvfrom(1024) # 等待回复
            #打印消息
            print(data.decode())
    
    
    
    
    
    
    def main():
        #创建用户套接字
        sock = socket(AF_INET,SOCK_DGRAM)
        #进入聊天室
        name=login(sock)
        #创建接收消息的子进程
        server_process = Process(target=get,args=(sock,))
        #父进程结束则结束子进程
        server_process.daemon=True
        #启动子进程
        server_process.start()
        #父进程发送消息
        put(sock, name)
    
    if __name__ == '__main__':
        main()
  • 相关阅读:
    上云,你真的只差一本葵花宝典
    Linux Kernel 4.11首个候选版本开放下载
    Windows 10 host where Credential Guard or Device Guard is enabled fails when running Workstation (2146361)
    .NET技术+25台服务器怎样支撑世界第54大网站
    Azure 订阅和服务限制、配额和约束
    python再议装饰器
    python的上下文管理器-1
    python的上下文管理器
    python小知识点
    python做简易记事本
  • 原文地址:https://www.cnblogs.com/yongqi-wang/p/13301311.html
Copyright © 2011-2022 走看看