AI智能
改变未来

基于数据包(UDP)的简易网络聊天室

    话不多说,直接上代码.

    服务器端:

    server.py

from socket import *
import os,sys
\’\’\’
聊天室文件
服务端
by:dyh
\’\’\’
###用户退出并且告知所有的用户###
def do_logout(s,user,name):
    #删除列表中的用户
    del user[name]
    msg=\’\\n\’+name+\’离开了聊天室\’
    for i in user:
        s.sendto(msg.encode(),addr)
    return
###用户登陆代码###
def do_login(s,user,name,addr):
    #用户注册时对用户name进行检查
    if (name in user) or name==\’管理员\’:
        s.sendto(\’该用户已存在\’.encode(),addr)
        return
    #用户name符合要求时发送OK给客户端提示其可以正常登陆
    #用户接收到信息以后对信息判断进行登陆操作
    s.sendto(b\’OK\’,addr)
    msg=\’\\n欢迎%s进入聊天室\’%name
    #通知所有人
    for i in user:
        s.sendto(msg.encode(),user[i])
    #将用户插进字典
    user[name]=addr
    return

def do_chat(s,user,cmd):
    msg=\’\\n%-4s:%s\’%(cmd[1],\’ \’.join(cmd[2:]))
    #将用户name发送给除了自己之外的所有人
    for i in user:
        if i!=cmd[1]:
            s.sendto(msg.encode(),user[i])
    return

#处理客户端请求
def do_child(s):
    #字典存储用户信息
    user={}
    #循环接收请求
    while True:
        msg,addr=s.recvfrom(1024)
        msg=msg.decode()
        cmd=msg.split(\’.\’)
        #根据不同请求做不同的事情
        if cmd[0]==\’l\’:
            do_login(s,user,cmd[1],addr)
            s.sendto(b\’OK\’,addr)
        elif cmd[0]==\’m\’:
            do_chat(s,user,cmd)
        elif cmd[0]==\’q\’:
            do_logout()
        else:
            s.sendto(\’请求错误\’.encode(),addr)

#发送管理员消息
def do_parent(s,ADDR):
    while True:
        msg=input(\’管理员发消息:\’)
        msg=\’m.管理员\’+msg
        s.sendto(msg.encode(),ADDR)
    s.close()
    sys.exit(0)

def main():
    if len(sys.argv)<3:
        print(\’argv error,\’)
        return
    HOST=sys.argv[1]
    PORT=int(sys.argv[2])
    ADDR=(HOST,PORT)

    #使用数据b报套接字
    s=socket(AF_INET,SOCK_DGRAM)
    #设置端口重用代码
    s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
    s.bind(ADDR)
    ###设置二级进程是为了将收消息和发消息分离###
    #创建一级子进程
    pid1=os.fork()

    if pid1<0:
        print()
    elif pid1==0:
        print(\’child process\’)
        pid2=os.fork()
        if pid2<0:
            print(\”\”)
        elif pid2==0:
            do_child(s)
        else:
            #一级子进程退出,使二级子进程成为孤儿
            os._exit(0)
    else:
        #等待一级子进程的退出
        os.wait()
        do_parent(s,ADDR)

if __name__==\’__main__\’:
    main()

    客户端:

    client.py

from socket import *
import os,sys,signal
\’\’\’
聊天室文件
客户端
by:dyh
\’\’\’
#发送消息
def do_child(s,name,addr):
    while True:
        text=input(\”say:\”)
        if text==\’quit\’:
            msg=\”q.\”+name
            s.sendto(msg.encode(),addr)
            #从子进程种杀掉父进程
            os.kill(os.getppid(),signal.SIGKILL)
            sys.exit(\’已退出!\’)
        else:
            msg=\’m.\’+\’%s.%s\’%(name,text)
            s.sendto(msg.encode(),addr)
#收消息        
def do_parent(s):
    while True:
        msg,addr=s.recvfrom(1024)
        msg=msg.decode()
        msg=msg[:-1]
        print(msg+\”\\nsay:\”,end=\’\’)

def main():
    if len(sys.argv)<3:
        print(\’argv error,\’)
        return
    HOST=sys.argv[1]
    PORT=int(sys.argv[2])
    ADDR=(HOST,PORT)

    #使用数据报套接字
    s=socket(AF_INET,SOCK_DGRAM)
    ####登陆###
    while True:
        name=input(\”请输入姓名:\”)
        msg=\’l.\’+name
        s.sendto(msg.encode(),ADDR)
        data,addr=s.recvfrom(1024)
        if data.decode()==\’OK\’:
            print(\’###进入聊天室###\’)
            break
        else:
            print(data.decode())
    ###注意这里不要设置二级进程###
    #如果设置可能会在关闭客户端的时候杀死系统进程导致关机
    pid=os.fork()

    if pid<0:
        print(\’ \’)
    elif pid==0:
        do_child(s,name,ADDR)
    else:
        #等待一级子进程的退出
        do_parent(s)

if __name__==\’__main__\’:
    main()

 

 

 

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 基于数据包(UDP)的简易网络聊天室