我是靠谱客的博主 干净星月,最近开发中收集的这篇文章主要介绍基于 python 和 UDP 协议实现简易聊天室(多人群聊)----详细解析带字幕,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

聊天室项目

功能介绍:
1.进入聊天室:输入姓名,用户名(不能重复)
2.某个成员进入聊天室后给其他所有所有成员发送消息
3.任何一个人发消息,其他人都会收到
4.某人退出聊天室,其他成员也会收到通知
5.管理员可以从后台发送消息,此时所有成员都可以接收

技术分析:
1.发消息(UDP 套接字)
2.成员的存储(服务器端:{} [])
3.消息发送模式
转发:消息发送给服务器,再转发给其他成员
4.管理员
保证收发消息互不影响(每个人收发消息都随机),发消息和收消息分别使用一个进程

整体设计:
1.封装方式(函数)
2.编写流程:先确保通信实现,然后逐个功能实现
3.测试:实现一个功能,测试一个功能

聊天室项目实现
1.网络通讯实现

1.服务器(创建一个 UDP 套接字,绑定地址)
        多进程,1个进程接收消息,一个进程管理员喊话
2.客户端

2.进入聊天室实现

1.服务器

        1.接收姓名,判断是否已经存在
            1.存在:返回值为不允许进入
            2.不存在:
                1.将用户加入存储结构
                2.通知其他成员:XXX 进入聊天室
        

    2.客户端
        1.输入姓名
        2.把姓名包装,发送给服务端
        3.接收服务端的反馈结果
            1.不允许进入(用户名重复), 需要重新输入姓名
            2.允许进入,创建进程,一个进程发送消息,一个进程接收消息

3.退出聊天室

    1.客户端发送退出消息
    2.客户端父子进程退出
    3.服务器接收退出请求
    4.服务器通知其他成员
    5.服务器从列表中删除用户

第一个模块:QQserver.py (服务器搭建)


"""
名称:网络聊天室
环境:Python 3.5
技术:socket, fork
"""

import socket
import os
import sys

#创建网络连接
def main():
    #创建 UDP 套接字
    server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)#设置端口复用

    server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)#绑定地址
    
    address = (('0.0.0.0',8888))
    server.bind(address)
    #创建多线程,让子进程负责管理员喊话,父进程和客户端交互
    
    pid = os.fork()
    
    if pid<0:#如果进程创建失败
        print('进程创建失败!')
        return

    elif pid == 0:#子进程的任务
        while True:
            content=input('管理员说话:')
            message="speak 管理员:%s" % content
            server.sendto(message.encode(),address)


    else:#父进程处理客户端的各种请求
        doRequest(server)


#处理客户端请求的函数
def doRequest(server):
    userlist={}#此字典用于存放客户端的名字和地址
    while True:
    #接收来自客户端的消息
        msg,addr = server.recvfrom(1024)
        msglist = msg.decode().split(' ')#拆分数据,以空格为分隔
        if msglist[0] == 'login':#如果是进入聊天室请求
            doLogin(server,userlist,msglist[1],addr)
        elif msglist[0] == 'speak':
            #msglist:['c','name','content']
            content = ' '.join(msglist[2:])#获取完整发送内容
            #发送给其他所有成员
            doChat(server,content,userlist,msglist[1])

        elif msglist[0] == 'quit':
            doQuit(server,msglist[1],userlist)

#客户端退出处理函数
def doQuit(server,name,userlist):
    message = 'n%s 退出了聊天室' %name
    for u in userlist:
        if u!=name:
            server.sendto(message.encode(),userlist[u])
        else:
            server.sendto('exit'.encode(),userlist[name])
        #从存储结构中删除
    del userlist[name]

        
#用于聊天的函数(把内容发送给其他成员)
def doChat(server,content,userlist,name):
    message = 'n%s 说:%s' % (name,content)
    for u in userlist:
        if u!= name:#发给不是自身的所有客户端
            server.sendto(message.encode(),userlist[u])


#列表用字典存储{name,addr}
#进入聊天室请求处理函数
def doLogin(server,userlist,name,addr):
    #判断姓名是否同名
    if (name in userlist) or name == '管理员':#如果列表中已经存在此用户名,或取名为管理员
        server.sendto('该用户已经存在!'.encode(),addr)
        return#函数结束,返回继续接收新的数据

    #同名不存在,发送信号给客户端,运行进入
    server.sendto('OK'.encode(),addr)
    #通知所有人
    message='n欢迎%s进入聊天室'%name
    for u in userlist:
        server.sendto(message.encode(),userlist[u])#全发
    userlist[name]=addr#加入到存储结构userlist字典中
    print(userlist)


if __name__ == '__main__':
    main()

第二个模块:QQclient.py (客户端搭建)

import socket
import os
import sys

def main():
    #从命令行输入IP地址和端口号
    if len(sys.argv)<3:
        print('参数错误!')
        return

    address = (sys.argv[1],int(sys.argv[2]))
    #创建 UDP 套接字
    client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

    #接收用户输入,包装后发送给服务器
    while True:
        name = input('请输入姓名:')
        message = 'login ' + name#此处加入标记
        client.sendto(message.encode(),address)
        data,addr = client.recvfrom(1024)
        if data.decode() == 'OK':
            print('您已经进入聊天室...')
            break

        else:#不允许进入
            #打印不允许进入的原因
            print(data.decode())

        #创建进程
    pid = os.fork()
    if pid<0:
        sys.exit('创建进程失败!')

    elif pid == 0:
        sendmsg(client,name,address)

    else:
        recvmsg(client)

def sendmsg(client,name,address):
    #发送消息给服务器,服务器群发给所有客户端
    while True:
        content=input('请发言(输入quit 退出):')
        if content == 'quit':
            message =  'quit ' + name
            client.sendto(message.encode(),address)
            sys.exit('已退出聊天室')#子进程退出

        #包装消息
        message = 'speak %s %s' % (name,content)
        client.sendto(message.encode(),address)
    

def recvmsg(client):
    while True:
        message,addr = client.recvfrom(1024)
        if message.decode() == 'exit':#如果收到服务器此消息,父进程退出
            os._exit(0)
        #因为print覆盖了之前的input界面,在这里重新输出一遍
        print(message.decode()+'n请发言(quit退出):',end='')

if __name__ == "__main__":
    main()



本人原创,欢迎转载~

最后

以上就是干净星月为你收集整理的基于 python 和 UDP 协议实现简易聊天室(多人群聊)----详细解析带字幕的全部内容,希望文章能够帮你解决基于 python 和 UDP 协议实现简易聊天室(多人群聊)----详细解析带字幕所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部