Python网络编程---实现聊天室

写一个聊天室
要求:
1.进入聊天室需要输入姓名,姓名不能重复
2.有人进入聊天室会想其他人发送通知,xxx 进入了聊天室
3.一个人发消息,其他人会收到消息
xxx 说:xxxx
4.某人退出聊天室,其他人也会收到通知
xxx 退出了聊天室
5.管理员喊话功能

-基于udp的网络传输

  • 服务端:

#!/usr/bin/env python3
#coding=utf-8
'''
name:xx
email:xxx
data:2018/9/11
introduce:Chatroom server
env:python3.5
'''
from socket import *
import os,sys

#登录判断
def do_login(s,user,name,addr):
    if (name in user) or name == '管理员':
        s.sendto('\n该用户已存在'.encode(),addr)
        return
    s.sendto(b'OK',addr)

    #通知其他人
    msg='\n欢迎%s进入聊天室' % name
    for i in user:
        s.sendto(msg.encode(),user[i])
    #插入用户
    user[name] = addr 

#消息发送
def do_chat(s,user,name,text):
    msg = '\n%s说:%s' % (name,text)
    for i in user:
        if i !=name:

#退出聊天室
def do_quit(s,user,name):
    msg = '\n' +name + '退出了聊天室'
    for i in user:
        if i == name:
            s.sendto(b'EXIT',user[i])
        else:
            s.sendto(msg.encode(),user[i])
    #从字典中删除用户
    del user[name]

#接收客户端请求
def do_parent(s):
    #存储结构,{'zhangsan':('127.0.0.1',9999)}
    user = {}
    while True:    
        msg,addr = s.recvfrom(1024)
        msgList = msg.decode().split(' ')

        #区分请求类型
        if msgList[0] == 'L':
            do_login(s,user,msgList[1],addr)
        elif msgList[0] == 'C':
            do_chat(s,user,msgList[1],' '.join(msgList[2:]))
        elif msgList[0] == 'Q':
            do_quit(s,user,msgList[1])

#做管理员喊话
def do_child(s,addr):
    while True:
        msg = input('管理员消息:')
        msg = 'C 管理员 ' + msg
        s.sendto(msg.encode(),addr)

#创建网络,创建进程,调用功能函数
def main():
    #定义server address
    ADDR = ('0.0.0.0',8888)

    #创建套接字
    s = socket(AF_INET,SOCK_DGRAM)
    s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
    s.bind(ADDR)

    #创建一个单独的进程处理管理员喊话功能
    pid = os.fork()
    if pid < 0:
        sys.exit('创建进程失败')
    elif pid == 0:
        do_child(s,ADDR)
    else:
        do_parent(s)

if __name__ == '__main__':
    main()
  • 客户端
from socket import *
import os,sys

#发送消息
def send_msg(s,name,addr):
    while True:
        text = input('发言:')
        #如果输入quit表示退出
        if text.strip() == 'quit':
            msg = 'Q ' + name
            s.sendto(msg.encode(),addr)
            sys.exit('退出聊天室')
        msg = 'C %s %s' % (name,text)
        s.sendto(msg.encode(),addr)

#接收消息
def recv_msg(s):
    while True:
        data,addr = s.recvfrom(2048)
        if data.decode() == 'EXIT':
            sys.exit(0)
        print(data.decode() + '\n发言:',end='')

#创建套接字,登录,如果登录成功,创建子进程
def main():
    #从命令行获取服务端地址
    if len(sys.argv) < 3:
        print('argv is 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:
        sys.exit('创建子进程失败')
    elif pid == 0:
        send_msg(s,name,ADDR)
    else:
        recv_msg(s)

if __name__ == '__main__':
    main() 

总结:
1、聊天室通过服务端转发消息给所有客户端来实现群聊的功能。
2、采用基于udp的网络传输来完成。
3、采用多进程编程,父子进程分别处理消息的接收和发送

猜你喜欢

转载自blog.csdn.net/sinat_34246179/article/details/82634347