聊天室案例代码

#注册会员聊天
#聊天室服务器
from socket import * 
import sys 
import os
import signal

def do_login(s,user,name,addr):
    for i in user:
        if i == name or name == '管理员':
            s.sendto(b'FAIL',addr)
            return
    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,tmp):
    #tmp = ['C','zhangsan','I','love','china']
    msg = '\n%-4s: %s'%\
    (tmp[1],' '.join(tmp[2:]))

    #给所有人转发消息除了自己
    for i in user:
        if i != tmp[1]:
            s.sendto(msg.encode(),user[i])
    return

def do_quit(s,user,name):
    #从用户字典删除该用户
    del user[name]

    msg = '\n' + name + '离开了聊天室'
    #讲用户退出的消息告知其他用户
    for i in user:
        s.sendto(msg.encode(),user[i])
    return

#接收处理
def do_child(s):
    #存储用户
    user = {}
    while True:
        #接收请求
        msg,addr = s.recvfrom(1024)
        msg = msg.decode()
        tmp = msg.split(' ')
        #L name
        if tmp[0] == 'L':
            do_login(s,user,tmp[1],addr)
        #C name text
        elif tmp[0] == 'C':
            do_chat(s,user,tmp)
        #Q name
        elif tmp[0] == 'Q':
            do_quit(s,user,tmp[1])

#发送系统消息
def do_parent(s,addr):
    name = 'C 管理员 '
    while True:
        msg = input("管理员消息:")
        msg = name + 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)
    #创建数据报套接字
    s = socket(AF_INET,SOCK_DGRAM)
    s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
    s.bind(ADDR)

    #处理僵尸进程
    signal.signal(signal.SIGCHLD,signal.SIG_IGN)

    #创建进程
    pid = os.fork()
    if pid < 0:
        print("create process failed")
        return
    elif pid == 0:
        do_child(s)
    else:
        do_parent(s,ADDR)

if __name__ == "__main__":
    main()
#管理员发言
#聊天室客户端 
from socket import *
import sys 
import os 
import signal 

#发送请求,消息
def do_child(s,addr,name):
    while True:
        text = input('发言:')
        #表示用户要退出聊天
        if text == 'quit':
            msg = 'Q ' + name 
            s.sendto(msg.encode(),addr)
            os.kill(os.getppid(),signal.SIGKILL)
            sys.exit(0)
        #正常聊天
        else:
            msg = 'C %s %s'%(name,text)
            s.sendto(msg.encode(),addr)
#接收
def do_parent(s):
    while True:
        msg,addr = s.recvfrom(1024)
        print(msg.decode()+'\n发言:',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)
    s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)

    while True:
        name = input("请输入姓名:")
        msg = 'L ' + name
        s.sendto(msg.encode(),ADDR)
        data,addr = s.recvfrom(1024) 
        if data.decode() == 'OK':
            break
        else:
            print("用户名已存在")

    signal.signal(signal.SIGCHLD,signal.SIG_IGN)

    #创建进程
    pid = os.fork()
    if pid < 0:
        print("create process failed")
        return
    elif pid == 0:
        do_child(s,addr,name)
    else:
        do_parent(s)


if __name__ == "__main__":
    main()

猜你喜欢

转载自www.cnblogs.com/-hjj/p/9939513.html