概述
聊天室项目
功能介绍:
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 协议实现简易聊天室(多人群聊)----详细解析带字幕所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复