使用Twisted框架做聊天室

首先需要下载

py -3 -m pip install twisted

py -3 -m pip install  Pywin32

# 服务端
# encoding=utf-8
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver  # 事件处理器
from twisted.internet import reactor


class Chat(LineReceiver):
    message_dict = {}

    def __init__(self, users):
        self.users = users
        self.name = None
        self.state = "GETNAME"

    def connectionMade(self):  # 连接开始,且开始做处理
        if self.name is None:
            self.sendLine("请输入用户名".encode("utf-8"))

    def connectionLost(self):
        if self.name in self.users:
            del self.users[self.name]
            try:
                del Chat.message_dict[self.name]
            except:
                print("删除用户的聊天记录失败")

    def lineReceived(self, line):  # 对返回内容开始做处理
        if self.state == "GETNAME" and "getmessage" not in line.decode("utf-8"):  # 根据状态开始选择不同得内容处理
            print("line:", line)
            self.handle_GETNAME(line.decode("utf-8"))
        else:
            self.handle_CHAT(line.decode("utf-8"))

    def handle_GETNAME(self, name):
        if name in self.users:
            self.sendLine("谢谢,请做另外得选择.\n".encode("utf-8"))  # 每个用户只能有一个聊天通信存在
            return
        self.sendLine(("欢迎, %s!\n" % name).encode("utf-8"))
        self.name = name
        self.users[name] = self
        self.state = "CHAT"

    def handle_CHAT(self, message):  # 对正在聊天得用户进行发送消息

            if ":" in message and "getmessage" not in message:
                username = message.split(":")[0]
                if username not in Chat.message_dict:
                    Chat.message_dict[username] = []

                Chat.message_dict[username].append(message)
                print(message, "---->", "增加了用户发送的消息:%s" %message , "\n")
                return
            elif "getmessage" in message:
                username = message.split(":")[0]
                print("*"*2,username,Chat.message_dict)
                if (username  not in Chat.message_dict) or  Chat.message_dict[username] == []:
                    self.users[username].sendLine("没有别人给你发送的数据".encode("utf-8"))
                    print(message,"---->","没有别人给你发送的数据","\n")
                    return
                message_indict=Chat.message_dict[username].pop(0)
                print(message_indict)
                send_message = message_indict.split(":")[1]
                username = message_indict.split(":")[0]
                if username in self.users:
                    print(username,self.users[username],self.users[username].name)
                    self.users[username].sendLine(("%s:%s" % (self.name, send_message)).encode("utf-8"))
                return
            elif message.strip() =="list":
                print("list response")
                self.sendLine((str([username for username in self.users]) + "\n").encode("utf-8"))
                print(message, "---->", (str([username for username in self.users]) + "\n"),"\n")
                return
            elif message.strip() =="bye":
                print("list response")
                self.sendLine(("Bye from server!\n").encode("utf-8"))
                print(message, "---->", (str([username for username in self.users]) + "\n"),"\n")
                return
            else:
                send_message = ("请指定用户名,按照格式‘用户名:消息’来进行发送。\n或者输入list查看当前登录用户\n输入getmessage\n")
                # print (type(send_message))
                self.sendLine(send_message.encode("utf-8"))
                print(message, "---->", send_message, "\n")
                return


class ChatFactory(Factory):
    def __init__(self):
        self.users = {}  # # 将所有与服务器端连接的对象存放到此字典中,所有的实例均可以使用此字典获取所有的连接对象

    def buildProtocol(self, addr):
        return Chat(self.users)


if __name__ == '__main__':
    reactor.listenTCP(1200, ChatFactory())
    print("开始进入监听状态...")
    reactor.run()
#客户端
# socket client end
from socket import *
import time
s = socket(AF_INET, SOCK_STREAM)
remote_host = gethostname()
print ('remote_host:', remote_host)
port = 1200
s.connect((remote_host, port))  # 发起连接
print (u"连接从", s.getsockname())  ##返回本地IP和端口
print (u"连接到", s.getpeername())  ##返回服务端IP和端口

print (u'从服务器返回消息:')
print (s.recv(1200).decode("utf-8").strip())

username = input("请输入你要使用的英文用户名:\n")
s.send(('%s\r\n' %username.strip()).encode("utf-8"))  # 发送一行字符串(以\r\n 结束)到服务器端
print (u'从服务器返回消息:')
print (s.recv(1200).decode("utf-8").strip())
print("*"*50)
print("""查看当前登录用户列表的命令:list
查看别人给你发送的消息命令要求:getmessage 
给别人发送消息的数据格式:username:要发送的消息  
""")
print("*"*50)


while 1:
    send_message=input("请输入发送的信息:\n")    
    if send_message=="getmessage" :
        s.send(('%s:%s\r\n' %(username,send_message)).encode("utf-8"))
        print (u'从服务器返回消息:')
        print (s.recv(1200).decode("utf-8").strip())
    elif send_message=="list":
        s.send(('%s\r\n' %send_message).encode("utf-8"))
        print (u'从服务器返回消息:')
        print (s.recv(1200).decode("utf-8").strip())
    elif send_message=="bye":
        s.send(('%s\r\n' %send_message).encode("utf-8"))
        print (u'从服务器返回消息:')
        print (s.recv(1200).decode("utf-8").strip())
        s.close()
        break
    else:
        s.send(('%s\r\n' %send_message.strip()).encode("utf-8"))
        time.sleep(1)
        continue

猜你喜欢

转载自www.cnblogs.com/su-sir/p/12690589.html