标题:用udp写的小型简单的聊天室模型,才学的,大神不要笑话
只看楼主
zxq0103
Rank: 1
等 级:新手上路
帖 子:36
专家分:0
注 册:2023-3-10
结帖率:0
 问题点数:0 回复次数:5 
用udp写的小型简单的聊天室模型,才学的,大神不要笑话
给象我一样的萌新看的,多进程我写不出同时收发信息,我用多线程写的

服务端:
程序代码:
from socket import *
import os,sys
from threading import Thread

"""
    UDP服务端
        协议:
            L:登陆
            C:聊天
            Q:退出
"""

ADDR = ('0.0.0.0',8888) # 服务端地址和端口
user = {} # 存储用户信息
no_word = ['你妈','你玛']
no_user = {}
no_chart = []

s = socket(AF_INET,SOCK_DGRAM)
s.bind(ADDR)

def do_login(name,addr) : # 登陆
    # print(name,user)
    if name in user:
        s.sendto(("用户名'%s'已存在,请换一个名字"%name).encode(),addr)
        return
    s.sendto(b'OK',addr) # 可以进入聊天室
    # 先通知其它人,再存储该名字
    msg = "C `系统信息:欢迎'%s'进入聊天室"%name
    for i in user:
        s.sendto(msg.encode(),user[i])
    user[name] = addr
    # print(user)

def do_chart(name,msg): # 聊天
    # print(name,msg)
    if name in no_user:
        if no_user[name] > 4:
            s.sendto(('C `系统提示:由于你多次发送不文明言语,你已经被禁言!').encode(),user[name])
            return
    msg = is_not_word(name,msg)
    # print(msg)
    for key,addr in user.items():
        if key != name:
            # print(key,addr)
            s.sendto(('C `'+name+' 说:'+msg).encode(),addr)
    return

def do_quit(name): # 退出
    msg = "C `系统信息:'%s'已退出聊天室"%name
    for i in user:
        s.sendto(msg.encode(),user[i])
    user.pop(name)
    # print(user)
    return

def do_request(s):
    while True:
        data,addr = s.recvfrom(1024)
        tmp = data.decode().split(' ')
        # print('收到信息:',data.decode())
        if tmp[0] == 'L': # 登陆
            do_login(tmp[1],addr)
        elif tmp[0] == 'C': # 聊天
            do_chart(tmp[1],tmp[2])
        elif tmp[0] == 'Q': # 退出
            do_quit(tmp[1])
        
def main():
    # 处理请求
    p_msg = Thread(target=to_msg)
    p_msg.start()
    do_request(s)

def to_msg():
    while True:
        msg = input()
        for i in user:
            s.sendto(("C `系统信息:"+msg).encode(),user[i])

def is_not_word(name,msg):
    for i in no_word:
        if i in msg:
            is_not_user(name)
            msg = msg.replace(i,'*')
            # print(msg)
    return msg

def is_not_user(name):
        if name not in no_user:
            no_user[name] = 1
        else:
            no_user[name] += 1
            print('被禁言用户列表:',no_user)

if __name__ == '__main__':
    main()

客户端
程序代码:
from socket import *
import os,sys
from threading import Thread

"""
    UDP客户端
        协议:
            L:登陆
            C:聊天
            Q:退出
"""

ADDR = ('127.0.0.1',8888)
s = socket(AF_INET,SOCK_DGRAM)

def main():
    name = to_login()
    p_recv = Thread(target=to_recv)
    p_recv.start()
    # to_recv()
    to_send(name)
    print('退出聊天室,程序结束')
    sys.exit()
    
def to_login():
    while True:
        name = input('请输入姓名>>')
        msg = 'L ' + name
        s.sendto(msg.encode(),ADDR)
        data,addr = s.recvfrom(128)
        print('收到信息:',data.decode())
        if data.decode() == 'OK':
            print('你已经入进聊天室',)
            return name
        else:
            print(data.decode())

def to_recv():
    while True:
        data = s.recv(1024)
        print(data.decode())
        tmp = data.decode().split(' `')
        print(tmp[1])
    
def to_send(name):
    while True:
        msg = input()
        if msg == 'q':
            msg = 'Q '+name
            s.sendto(msg.encode(),ADDR)
            sys.exit()
        else:
            msg = 'C '+name+' '+ msg
            s.sendto(msg.encode(),ADDR)
    
if __name__ == '__main__':
    main()
搜索更多相关主题的帖子: user name ADDR def print 
2023-04-16 18:03
东海ECS
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:Python
等 级:版主
威 望:19
帖 子:376
专家分:1454
注 册:2023-1-24
得分:0 
这是一个不错的UDP聊天室模型,虽然使用的是多线程而不是多进程,但是功能实现是相似的。在程序的基础上,你可以进一步学习和实践,尝试进行优化和升级,例如采用多进程、增加聊天记录保存、加入私聊等功能。好好学习,加油!

会当凌绝顶,一览众山小.
2023-04-16 19:39
东海ECS
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:Python
等 级:版主
威 望:19
帖 子:376
专家分:1454
注 册:2023-1-24
得分:0 
使用多进程的实现方法与使用多线程是相似的,只是要用 multiprocessing 库中的 Process 类来创建新的进程。同时,由于进程之间是相互独立的,需要使用 multiprocessing 库中的 Pipe 或 Queue 来进行进程间通信。

下面是使用多进程实现聊天室的示例代码:

服务端:

程序代码:
from socket import *
import os
import multiprocessing as mp

"""
    UDP服务端
        协议:
            L: 登陆
            C: 聊天
            Q: 退出
"""

ADDR = ('0.0.0.0', 8888)  # 服务端地址和端口
user = {}  # 存储用户信息
no_word = ['你妈', '你玛']
no_user = {}
no_chart = []

s = socket(AF_INET, SOCK_DGRAM)
s.bind(ADDR)


def do_login(name, addr, p):
    if name in user:
        p.send(("用户名'%s'已存在,请换一个名字" % name).encode())
        return

    p.send(b'OK')
    msg = "C `系统信息:欢迎'%s'进入聊天室" % name

    for i in user:
        s.sendto(msg.encode(), user[i])
    user[name] = addr


def do_chart(name, msg):
    if name in no_user:
        if no_user[name] > 4:
            s.sendto(('C `系统提示:由于你多次发送不文明言语,你已经被禁言!').encode(), user[name])
            return
    msg = is_not_word(name, msg)

    for key, addr in user.items():
        if key != name:
            s.sendto(('C `'+name+' 说:'+msg).encode(), addr)
    return


def do_quit(name):
    msg = "C `系统信息:'%s'已退出聊天室" % name

    for i in user:
        s.sendto(msg.encode(), user[i])

    user.pop(name)


def process_request(p,):
    while True:
        data, addr = s.recvfrom(1024)
        tmp = data.decode().split(' ')

        if tmp[0] == 'L':
            do_login(tmp[1], addr, p)
        elif tmp[0] == 'C':
            do_chart(tmp[1], tmp[2])
        elif tmp[0] == 'Q':
            do_quit(tmp[1])


def main():
    p_msg = mp.Process(target=to_msg)
    p_msg.start()

    while True:
        p = mp.Process(target=process_request, args=(mp.Pipe(),))
        p.start()

        # 等待进程结束
        p.join()

    p_msg.join()


def to_msg():
    while True:
        msg = input()

        for i in user:
            s.sendto(("C `系统信息:"+msg).encode(), user[i])


def is_not_word(name, msg):
    for i in no_word:
        if i in msg:
            is_not_user(name)
            msg = msg.replace(i, '*')

    return msg


def is_not_user(name):
    if name not in no_user:
        no_user[name] = 1
    else:
        no_user[name] += 1
        print('被禁言用户列表:', no_user)


if __name__ == '__main__':
    main()

客户端:

程序代码:
from socket import *
import os
import multiprocessing as mp

"""
    UDP客户端
        协议:
            L:登陆
            C:聊天
            Q:退出
"""

ADDR = ('127.0.0.1', 8888)
s = socket(AF_INET, SOCK_DGRAM)


def main():
    name = to_login()
    p_recv = mp.Process(target=to_recv)
    p_recv.start()
    to_send(name)

    print('退出聊天室,程序结束')
    sys.exit()


def to_login():
    while True:
        name = input('请输入姓名>>')
        msg = 'L ' + name

        s.sendto(msg.encode(), ADDR)
        data, addr = s.recvfrom(128)

        print('收到信息:', data.decode())

        if data.decode() == 'OK':
            print('你已经入进聊天室',)

            return name
        else:
            print(data.decode())


def to_recv():
    while True:
        data = s.recv(1024)
        print(data.decode())
        tmp = data.decode().split(' `')
        print(tmp[1])


def to_send(name):
    while True:
        msg = input()

        if msg == 'q':
            msg = 'Q ' + name
            s.sendto(msg.encode(), ADDR)
            sys.exit()
        else:
            msg = 'C ' + name + ' ' + msg
            s.sendto(msg.encode(), ADDR)


if __name__ == '__main__':
    main()

需要注意的是,使用多进程时需要考虑进程之间的通信和同步,否则可能会造成信息的丢失或冲突。同时多进程的资源开销要比多线程高,需要特别留意。




会当凌绝顶,一览众山小.
2023-04-16 19:43
东海ECS
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:Python
等 级:版主
威 望:19
帖 子:376
专家分:1454
注 册:2023-1-24
得分:0 
可以使用正则表达式实现对不文明用语的屏蔽。可以使用 re 模块中的 sub 函数对包含不文明用语的聊天内容进行替换。

例如,新建一个 filter_word 函数来对消息进行过滤:

程序代码:
import re

def filter_word(msg):
    pattern = '|'.join(no_word)
    return re.sub(pattern, '*', msg)

这里,我们使用了 join 函数将屏蔽列表 no_word 中的各个单词用 | 连接起来,形成一个正则表达式,然后使用 re.sub 将所有匹配的单词替换为 *,从而达到屏蔽的目的。

在 do_chart 函数中,我们可以调用 filter_word 函数对消息进行过滤:

程序代码:
def do_chart(name, msg):
    if name in no_user:
        if no_user[name] > 4:
            s.sendto(('C `系统提示:由于你多次发送不文明言语,你已经被禁言!').encode(), user[name])
            return
    msg = filter_word(msg)
    # ...

}
这样就可以在聊天室中实现对不文明用语的屏蔽了。

会当凌绝顶,一览众山小.
2023-04-16 19:45
zxq0103
Rank: 1
等 级:新手上路
帖 子:36
专家分:0
注 册:2023-3-10
得分:0 
回复 4楼 东海ECS
你上面的多进程的代码,我在VS里运行不了.
2023-04-16 22:53
zxq0103
Rank: 1
等 级:新手上路
帖 子:36
专家分:0
注 册:2023-3-10
得分:0 

2023-04-18 11:22



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-511931-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.053860 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved