グループチャットルーム

チャットルーム

  1. 需要分析:製品(クライアント)のVisioのプロトタイプを確立します

    必要に応じて、実現する機能を計画します

  2. テクニカル分析:機能に応じて実装技術を決定します

    ネットワーク通信:udpネットワークテクノロジー

ここに画像の説明を挿入

  消息收发模型
       * 转发   客户端--> 服务端-->其他客户端
       * 用户进入聊天室时要存储用户地址 怎么存
          {
    
    name:address}
          [(name,address),....]
          class Person:
              def __init__(self,name,address):
                  self.name = name
                  self.address = address
   * 收发消息互相不干扰
      父进程 发送消息
      子进程 接收消息
  1. 機能モジュール分析(パッケージ):分解
  • 1つの機能を実現する1つの機能をテストする

    • 関数ラッパー

    チャットルーム入力し
    たチャット
    チャットルームを終了します

  1. 通信プロトコルの設計

      请求类型     数据
    

  进入   L          name

   聊天   C          name   content

   退出   E          name

  1. サブモジュール固有のロジック設計

基本的なネットワーク構造を構築します
。サーバー:1。udpネットワーク通信を作成します
。2。クライアントメッセージを周期的に受信する準備をします。3
。要求に応じて適切な関数処理を呼び出します。

 客户端: 1.创建udp套接字

チャットルームに入る
クライアント:1。名前を入力します
2.リクエストを送信し
ます3.サーバーからの通知結果を受け入れます
4. Y次にNを入力し、名前を再入力します

 服务端: 1. 接收请求
  1. ユーザーが存在するかどうかを確認します
    。3。Yはクライアントに入力できないことを
    通知します。4。Nはクライアントにチャットルームに入るように通知します。
    他のユーザーに
    ユーザー情報保存するよう通知します。

チャットする

クライアント:1。子プロセスを作成します
2.子プロセスはメッセージを周期的に受信します
3.親プロセスはメッセージを周期的に入力して送信します

 服务端: 1. 接收消息
        2. 将消息转发给其他人

チャットルームを出て、出口に入り、サインアウトします

クライアント:1。終了は終了を意味します
2.メッセージを送信します
3.プロセスを終了します

サーバー:1。メッセージを受信します
2.他のユーザーに通知します
3.ユーザーを削除します

  1. 最適化

関数:qqグループ関数に似ています

[1]チャットルームに入るには誰かが名前を入力する必要があります。名前を繰り返すことはできません

[2]誰かがチャットルームに入ると、他の人は通知を受け取ります:xxxがチャットルームに入りました

[3] 1人がメッセージを送信すると、他の人は次のメッセージを受信します:xxx:xxxxxxxxxxx

[4]誰かがチャットルームを離れると、他の人にも通知が届きます:xxxがチャットルームを離れました

[5]拡張機能:サーバーはすべてのユーザーにアナウンスを送信できます:管理者メッセージ:xxxxxxxxx

"""
author: xx
email: [email protected]
time: 2020-8-10
env: Python 3.6
socket and Process
"""

from socket import *
from multiprocessing import Process

ここに画像の説明を挿入

サーバ

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

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


# 处理进入聊天室
def login(sock, name, addr):
    # 如果用户存在
    if name in user or "管理" in name:
        sock.sendto(b"FAIL", addr)
        return

    # 告知用户进入
    sock.sendto(b"OK", addr)
    # 告知其他用户
    msg = "欢迎 %s 进入聊天室" % name
    for i in user:
        sock.sendto(msg.encode(), user[i])
    # 增加用户
    user[name] = addr
    # print("测试:",user)


# 聊天
def chat(sock, name, content):
    msg = "%s : %s" % (name, content)
    # 循环发送
    for i in user:
        if i == name:
            continue
        sock.sendto(msg.encode(), user[i])


# 退出
def exit(sock, name):
    del user[name]  # 删除用户
    msg = "%s 退出了聊天室" % name
    # 循环发送
    for i in user:
        sock.sendto(msg.encode(), user[i])


# 子进程处理请求
def request(sock):
    # 循环接受客户端消息
    while True:
        # 所有请求都在这接受
        data, addr = sock.recvfrom(1024 * 10)
        # 对data做基本的解析
        tmp = data.decode().split(' ', 2)
        # 根据请求选择函数处理
        if tmp[0] == "L":
            # tmp --> ['L','name']
            login(sock, tmp[1], addr)
        elif tmp[0] == "C":
            # tmp -->  [C,name,content]
            chat(sock, tmp[1], tmp[2])
        elif tmp[0] == "E":
            # tmp --> [E,name]
            exit(sock, tmp[1])


# 启动函数用于搭建网络
def main():
    # UDP套接字
    sock = socket(AF_INET, SOCK_DGRAM)
    sock.bind(ADDR)

    # 创建子进程
    p = Process(target=request, args=(sock,))
    p.daemon = True
    p.start()
    while True:
        content = input("管理员消息:")
        # 服务端退出
        if content == "exit":
            break
        msg = "C 管理员消息 "+content
        # 从父进程发送给子进程
        sock.sendto(msg.encode(),ADDR)


if __name__ == '__main__':
    main()

ここに画像の説明を挿入

クライアント

"""
chat room  客户端
发送请求 接收消息
"""
from socket import *
from multiprocessing import Process
import sys

# 服务器地址
ADDR = ("124.70.148.168", 8000)


# 进入聊天室
def login(sock):
    while True:
        name = input("Name:")
        # 给服务端发请求
        msg = "L " + name  # 根据协议组织消息
        sock.sendto(msg.encode(), ADDR)
        # 等待结果
        result, addr = sock.recvfrom(128)
        # 约定OK作为请求成功的标志
        if result.decode() == 'OK':
            print("进入聊天室")
            return name  # 以name登录
        else:
            print("该用户已存在")


# 接收消息
def recv_msg(sock):
    while True:
        data, addr = sock.recvfrom(1024 * 10)
        # 美化打印内容
        msg = "\n" + data.decode() + "\n发言:"
        print(msg, end="")


# 发送消息
def send_msg(sock, name):
    while True:
        try:
            content = input("发言:")
        except KeyboardInterrupt:
            content = "exit"
        # 输入exit要退出
        if content == 'exit':
            msg = "E " + name
            sock.sendto(msg.encode(), ADDR)
            sys.exit("退出聊天室")
        msg = "C %s %s" % (name, content)
        sock.sendto(msg.encode(), ADDR)


def main():
    sock = socket(AF_INET, SOCK_DGRAM)
    sock.bind(('0.0.0.0',55667))
    # sock.sendto("测试信息".encode(),ADDR)

    # 进入聊天室
    name = login(sock)

    # 创建子进程
    p = Process(target=recv_msg, args=(sock,))
    p.daemon = True  # 子进程随父进程退出
    p.start()
    send_msg(sock, name)  # 父进程发送消息


if __name__ == '__main__':
    main()

実行では、最初にサーバーを実行し、次にクライアントを実行する必要があります

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_49304690/article/details/112428150