#注册会员聊天 #聊天室服务器 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()