0
点赞
收藏
分享

微信扫一扫

python qq聊天室


1. 群聊聊天室

功能: 类似QQ群功能

  1. 有人进入聊天室树要输入姓名,姓名不能重复
  2. 有人进入聊天室时,其他人会收到通知: xxx 进入聊天室
  3. 一个人发消息,其他人会收到: xxx: xxxxxx
  4. 有人退出聊天室,则其他人也会收到通知:xxx 推出了聊天室
  5. 扩展功能: 服务器可以向所有用户发送公告:管理员消息:xxxxx

2. 技术点的确定

  • 数据如何流转
  • 转发: 客户端>服务端>其他客户端
  • 网络模型如何构建
  • 构建UDP数据传输
  • 用户信息在哪维护怎么维护
  • 服务端:{name:address}或者[(name,address),]
  • 随意收发消息如何避免阻塞
  • 收发分别使用不同的进程执行

3. 结构设置注意事项

  • 采用什么封装结构: 函数
  • 编写一个功能测试一个功能
  • 注意注释和结构的设计

4.分析功能模块

  • 网络搭建
  • 进入聊天室
  • 客户端:
  • 输入姓名
  • 将请求发送给服务器
  • 接收结果
  • 允许则可以聊天,不允许则重新输入姓名
  • 服务单:
  • 接收请求
  • 判断 是否存在用户名
  • 如果允许进入则将用于存储,通知其他客户端
  • 如果不允许则结束
  • 将结果通知客户端
  • 聊天
  • 客户端:
  • 创建新的进程
  • 一个进程循环发送消息
  • 一个进程循环接收消息
  • 服务端
  • 接收请求
  • 判断请求类型
  • 将消息转发给其他人
  • 退出聊天室
  • 客户端
  • 输入quit或者ctrl-c退出
  • 将请求发送给服务端
  • 结束进程
  • 服务端
  • 接收请求
  • 将退出消息告知其他人
  • 给该用户发送exit
  • 删除用户
  • 管理员消息
  • 没有做

5.图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pqcx3NOL-1639530767665)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211214192723554.png)]

6.通信协议设置

  • 进入聊天室: L
  • 聊天: C
  • 退出: Q
  • 服务器反馈: ok成功 其他表示失败
  • 客户端收到:exit 退出接收进程
  • 客户端输入:quit 直接退出

7. 服务端代码

"""
服务器端
"""
from socket import *
import time

# 服务器地址
ADDR = ('0.0.0.0', 18888)
OK = 'OK'
list_client = []


# 判断是否存在列表里面 如果不存在就加入列表
def is_exeit(name):
global list_client
for item, addr in list_client:
if item == name:
return False
return True


def add_to_list(flag, name, addr):
if flag:
global list_client
list_client.append((name, addr))


# 返回结果
def send_result(flag, addr, s):
s.sendto(OK.encode(), addr) if flag else s.sendto("不允许".encode(), addr)


# 通知其他人
def send_all(flag, msg, s):
if flag:
global list_client
for item, addr in list_client:
s.sendto(msg.encode(), addr)


def do_quit(s, name):
global list_client
r_name, r_addr = ('', '')
for item, addr in list_client:
if item == name:
r_name, r_addr = item, addr
s.sendto('exit'.encode(), addr)
else:
s.sendto((name + ' 退出了').encode(), addr)
list_client.remove((r_name, r_addr))


# 处理请求
def do_chat(s, name, msg):
global list_client
for item, addr in list_client:
t_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
s.sendto(('%s %s:%s' % (t_str, name, msg)).encode(), addr)


# 登录
def do_login(addr, name, s):
# 判断 是否 允许进入 如果允许进入
flag = is_exeit(name)
# 通知其他人
send_all(flag, '欢迎"%s"进入聊天室' % name, s)
# 存储结果
add_to_list(flag, name, addr)
# 返回结果
send_result(flag, addr, s)


def do_request(s):
global list_client
# 循环收发消息
while True:
data, addr = s.recvfrom(1024)
arr = data.decode().split(' ')
state, name = arr[0], arr[1]
if state == 'L':
# 登录
do_login(addr, name, s)
print(list_client)
elif state == 'C':
# 群发
msg = ' '.join(arr[2:])
do_chat(s, name, msg)

elif state == 'Q':
do_quit(s, name)
print(list_client)


# 搭建网络
if __name__ == '__main__':
# udp服务端
s = socket(AF_INET, SOCK_DGRAM)
s.bind(ADDR)

# 请求处理函数
do_request(s)
print('退出程序')

8.客户端代码

"""
客户端
发送请求,暂时结果
"""
import os
import sys

from socket import *
from multiprocessing import Process # 导入模块
import time

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


def recv_msg(s):
while True:
try:
data, addr = s.recvfrom(4096)
if data.decode() == 'exit':
break
print(data.decode())
except:
print('发送内容异常')
break


def send_msg(s, name, addr, fn):
sys.stdin = os.fdopen(fn)
while True:
try:
data = input('')
if data == "quit":
msg = 'Q ' + name
s.sendto(msg.encode(), addr)
break
msg = 'C %s %s' % (name, data)
s.sendto(msg.encode(), addr)

except:
msg = 'Q ' + name
s.sendto(msg.encode(), addr)
print('输入内容异常')
break


# 客户端启动函数
if __name__ == '__main__':


fn = sys.stdin.fileno()
s = socket(AF_INET, SOCK_DGRAM)
# 进入聊天室
while True:
name = input("请输入姓名:")
msg = 'L ' + name
s.sendto(msg.encode(), ADDR)
msg, addr = s.recvfrom(1024)
if msg.decode() == OK:
print('您已经进入聊天室')
break

# 创建进程 收发消息
# 接收消息
recv_process = Process(target=recv_msg,
name='recv_process', args=(s,))
# 发送消息
send_process = Process(target=send_msg,
name="send_process", args=(s, name, addr, fn))
# 启动 接收消息进程
recv_process.start()
# 启动 发送消息进程
send_process.start()
# 等待进程结束
try:
recv_process.join()
send_process.join()
print('结束聊天')
except:
print('异常退出?')


举报

相关推荐

0 条评论