python版 聊天软件

#! /usr/bin/python3.4

from tkinter import *
from tkinter.filedialog import askopenfilename
import time
from threading import Thread
import socket
import sys
import os.path
import process

#聊天实现类
class ChatClient(Thread):
    #构造函数
    def __init__(self):
        Thread.__init__(self)
        #提示信息输出
        self.__info_event=None
        #读取数据输出
        self.__out_event=None
        #创建套接字
        self.clientSock=socket.socket()
        #重用地址
        self.clientSock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

    #返回提醒信息
    #info事件
    @property
    def info_event(self):
        return self.__info_event
    @info_event.setter
    def info_event(self,handler):
        self.__info_event=handler
    #info输出
    def info(self,content):
        if self.info_event!=None:
            self.info_event(content)
    #返回接收结果
    #out事件
    @property
    def out_event(self):
        return self.__out_event
    @out_event.setter
    def out_event(self,handler):
        self.__out_event=handler
    #out输出
    def out(self,content):
        if self.out_event!=None:
            self.out_event(content)

    #发送信息
    def send(self,content):
        if self.clientSock==None:
            self.info("已经断开连接")
            return -1
        if type(content) is str:
            content=content.encode()
        elif type(content) is bytes:
            pass
        else:
            self.info("发送信息类型错误")
            return -1
        try:
            self.clientSock.send(content)
            #self.info("已经发送信息")
            return 0
        except:
            self.info("丢失连接")
            return -1

    #接受信息
    def recv(self):
        recv_msg={}
        if self.clientSock==None:
            return
        fileobj=self.clientSock.makefile("rb")
        while True:
            try:
                line=fileobj.readline()
            except:
                return None
            if not len(line):
                return None
            elif line==b"\r\n":
                break
            else:
                #print(line)
                key,value=line.decode().strip().split(": ")
                recv_msg[key]=value
        if "Length" in recv_msg:
            length=int(recv_msg["Length"])
            recv_msg["Content"]=b""
            while length>0:
                r=fileobj.read(min(1024,length))
                length-=len(r)
                recv_msg["Content"]+=r
            fileobj.close()
        elif "Count" in recv_msg:
            count=int(recv_msg["Count"])
            #print(count)
            recv_msg["Content"]=b""
            while count>0:
                recv_msg["Content"]+=fileobj.readline()
                count-=1
            fileobj.close()

        return recv_msg

    def run(self):
        while True:
            recv_msg=self.recv()
            if recv_msg==None:
                break
            self.out(recv_msg)

    #连接chat服务器
    def connserver(self,servername,serverport):
        try:
            self.clientSock.connect((servername,serverport))
            #self.info("成功连接pchat服务器")
            return 0
        except BaseException as e:
            self.info("连接pchat服务器失败")
            return -1

    #断开连接
    def disconnserver(self):
        if self.clientSock!=None:
            self.clientSock.close()
            self.clientSock=None
        self.info("断开连接")
        return 0

#主界面类
class MainWindow(Tk):
    #构造函数
    def __init__(self,name,pwd,chatwith=None):
        Tk.__init__(self)
        #用户名属性
        self.username=name
        self.password=pwd
        self.chatwith=chatwith
        self.init()
        self.conn()

    def conn(self,host="127.0.0.1",port=1234):
        #初始化chatclient
        self.chatclient=ChatClient()
        #添加事件处理
        self.chatclient.info_event=self.info
        self.chatclient.out_event=self.out
        #连接
        r=self.chatclient.connserver(host,port)
        #开始接收服务器发送的数据
        self.chatclient.start()
        return r

    #属性用户名
    @property
    def username(self):
        return self.__username

    @username.setter
    def username(self,name):
        self.__username=name
    @property
    def password(self):
        return self.__password
    @password.setter
    def password(self,pwd):
        self.__password=pwd
    #属性 聊天对象
    @property
    def chatwith(self):
        return self.__chatwith
    @chatwith.setter
    def chatwith(self,name):
        self.__chatwith=name

    #初始化菜单
    def init_menu(self):
        menubar=Menu(self,bg="lightblue")
        self["menu"]=menubar
        sysmenu=Menu(menubar,bg="lightblue")
        menubar.add_cascade(label="系统",menu=sysmenu)
        #下拉菜单
        sysmenu.add_command(label="配置",command=self.clientConfigure)
        sysmenu.add_separator()
        sysmenu.add_command(label="登陆",command=self.login)
        sysmenu.add_command(label="注册",command=self.register)
        sysmenu.add_command(label="注销",command=self.outlogin)
        sysmenu.add_separator()
        sysmenu.add_command(label="结束",command=self.destroy)

    #设置标题
    def setTitle(self,name):
        self.title("【%s】PChat [%s]"%(self.username,name))

    #界面初始化
    def init(self):
        self.setTitle(self.chatwith)
        self.init_menu()

        left_frame=Frame(self)
        left_frame.pack(expand=YES,fill=BOTH,side=LEFT)
        right_frame=Frame(self)
        right_frame.pack(fill=Y,side=LEFT)
        self.friends_list=Listbox(right_frame,bg="lightblue")
        self.friends_list.pack(expand=YES,fill=BOTH)
        self.friends_list.bind("<Double-Button-1>",self.select_friend)
        self.friend_entry=Entry(right_frame)
        self.friend_entry.pack(fill=X)
        self.flush_button=Button(right_frame,text="刷新",command=self.flush)
        self.flush_button.pack(side=LEFT)
        self.add_button=Button(right_frame,text="增加",command=self.add)
        self.add_button.pack(side=LEFT)
        self.delete_button=Button(right_frame,text="删除",command=self.delete)
        self.delete_button.pack(side=LEFT)

        text_frame=Frame(left_frame,bg="white")
        text_frame.pack(expand=YES,fill=BOTH)
        self.chatmessage_text=Text(text_frame,bg="lightblue")
        self.chatmessage_text.pack(expand=YES,fill=BOTH,side=LEFT)
        text_scroll_bar=Scrollbar(text_frame,command=self.chatmessage_text.yview,bg="lightblue")
        text_scroll_bar.pack(fill=Y,side=RIGHT)
        self.chatmessage_text.configure(yscrollcommand=text_scroll_bar.set)
        self.chatmessage_text.tag_config("header",foreground="green",font=("Arial",15))
        self.chatmessage_text.tag_config("information",foreground="red",font=("Arial",10))
        self.chatmessage_text.tag_config("file",foreground="yellow",font=("Arial",18))
        self.chatmessage_text.tag_config("body",foreground="gray",font=("Arial",18))


        self.inputmessage_string=StringVar()
        self.inputmessage_entry=Entry(left_frame,bg="lightblue",textvariable=self.inputmessage_string)
        self.inputmessage_entry.pack(fill=X)
        self.inputmessage_entry.bind("<Return>",self.send)
        self.send_button=Button(left_frame,text="发送",command=self.send,bg="lightblue")
        self.send_button.pack(side=LEFT)

        self.send_file_button=Button(left_frame,text="发送文件",command=self.sendfile)
        self.send_file_button.pack(side=LEFT)

        self.bottom_frame=Frame(self)
        self.bottom_frame.pack(side=TOP,fill=X)

        #self.usersname_label=Label(self.bottom_frame,text="用户名:")
        #self.usersname_label.pack(side=LEFT)
        #添加关闭窗口的事件处理
        self.protocol("WM_DELETE_WINDOW",self.destroy)

    def select_friend(self,event=None):
        if len(event.widget.curselection()):
            chatwith=event.widget.get(event.widget.curselection()[0])
            if chatwith!="":
                self.chatwith=chatwith
                self.setTitle(self.chatwith)

    #使用chatclietn发送数据
    def __send(self,From,To,Date,Type,Length,content,Name=None):
        if self.chatclient==None:
            self.info("未连接服务器")
            return -1
        r=self.chatclient.send("From: "+From+"\r\n")
        if r==-1:
            return -1
        r=self.chatclient.send("To: "+To+"\r\n")
        if r==-1:
            return -1
        r=self.chatclient.send("Date: "+Date+"\r\n")
        if r==-1:
            return -1
        r=self.chatclient.send("Type: "+Type+"\r\n")
        if r==-1:
            return -1
        r=self.chatclient.send("Length: "+str(Length)+"\r\n")
        if r==-1:
            return -1
        if Name!=None:
            r=self.chatclient.send("Name: "+Name+"\r\n")
            if r==-1:
                return -1
        r=self.chatclient.send("\r\n")
        if r==-1:
            return -1
        r=self.chatclient.send(content)
        if r==-1:
            return -1
        return 0

    #刷新列表按钮事件处理
    def flush(self,event=None):
        cur_time=time.localtime()
        text="".encode()
        self.__send(self.username,"pchatsvr","%d:%d:%d"%(cur_time.tm_hour,cur_time.tm_min,cur_time.tm_sec),"List",len(text),text)

    def add(self,event=None):
        friend_name=self.friend_entry.get().strip()
        if friend_name!="":
            cur_time=time.localtime()
            text=friend_name.encode()
            self.__send(self.username,"pchatsvr","%d:%d:%d"%(cur_time.tm_hour,cur_time.tm_min,cur_time.tm_sec),"Add",len(text),text)

    def delete(self,event=None):
        friend_name=self.friend_entry.get().strip()
        if friend_name!="":
            cur_time=time.localtime()
            text=friend_name.encode()
            self.__send(self.username,"pchatsvr","%d:%d:%d"%(cur_time.tm_hour,cur_time.tm_min,cur_time.tm_sec),"Delete",len(text),text)


    #发送信息按钮事件处理
    def send(self,text=None):
        if self.chatwith==None:
            self.info("请选择聊天对象")
            return
        if self.inputmessage_string.get().strip()=="":
            return
        cur_time=time.localtime()
        self.chatmessage_text.insert(END,"%s %d:%d:%d\n"%(self.username,cur_time.tm_hour,cur_time.tm_min,cur_time.tm_sec),"header")
        self.chatmessage_text.insert(END,self.inputmessage_string.get()+"\n","body")
        text=(self.inputmessage_string.get()).encode()
        self.__send(self.username,self.chatwith,"%d:%d:%d"%(cur_time.tm_hour,cur_time.tm_min,cur_time.tm_sec),"Plain",len(text),text)
    #发送文件按钮响应事件
    def sendfile(self):
        filename=askopenfilename()
        if filename!="":
            self.info("将发送文件:"+filename)
            f=open(filename,"rb")
            filecontent=f.read()
            f.close()
            cur_time=time.localtime()
            self.__send(self.username,self.chatwith,"%d:%d:%d"%(cur_time.tm_hour,cur_time.tm_min,cur_time.tm_sec),"File",len(filecontent),filecontent,os.path.basename(filename))
        else:
            self.info("请选择文件")

    #系统配置
    def clientConfigure(self):
        print("配置客户端")

    #登陆
    def login(self):
        cur_time=time.localtime()
        text=(self.username+"&"+self.password).encode()
        self.__send(self.username,"pchatsvr","%d:%d:%d"%(cur_time.tm_hour,cur_time.tm_min,cur_time.tm_sec),"Login",len(text),text)
    #注册
    def register(self):
        cur_time=time.localtime()
        text=(self.username+"&"+self.password).encode()
        self.__send(self.username,"pchatsvr","%d:%d:%d"%(cur_time.tm_hour,cur_time.tm_min,cur_time.tm_sec),"Register",len(text),text)

    #注销
    def outlogin(self):
        cur_time=time.localtime()
        text=("").encode()
        self.__send(self.username,"pchatsvr","%d:%d:%d"%(cur_time.tm_hour,cur_time.tm_min,cur_time.tm_sec),"Outlogin",len(text),text)

    #结束
    def destroy(self):
        cur_time=time.localtime()
        text=("").encode()
        r=self.__send(self.username,"pchatsvr","%d:%d:%d"%(cur_time.tm_hour,cur_time.tm_min,cur_time.tm_sec),"Quit",len(text),text)
        if r==-1:
            Tk.destroy(self)

    #打开文件事件处理
    def open(self,event):
        #os.system("xdg-open %s"%("./recvfiles/"+event.widget["text"]))
        process.system("/usr/bin/xdg-open %s"%("./recvfiles/"+event.widget["text"]))
    #解析服务器响应
    def parse(self,recv_msg):
        if recv_msg["Type"]=="Plain":
            self.chatmessage_text.insert(END,"%s %s\n"%(recv_msg["From"],recv_msg["Date"]),"header")
            self.chatmessage_text.insert(END,recv_msg["Content"].decode()+"\n","body")
        elif recv_msg["Type"]=="File":
            #创建目录
            try:
                os.mkdir("./recvfiles")
            except FileExistsError as e:
                pass
            f=open("./recvfiles/"+recv_msg["Name"],"wb")
            f.write(recv_msg["Content"])
            f.close()
            filelabel=Label(self.chatmessage_text,fg="yellow",bg="lightblue",text=recv_msg["Name"],font=("宋体",15))
            filelabel.bind("<Double-Button-1>",self.open)
            self.chatmessage_text.insert(END,"%s %s\n"%(recv_msg["From"],recv_msg["Date"]),"header")
            self.chatmessage_text.window_create(END,window=filelabel)
            self.chatmessage_text.insert(END,"\n")
        elif recv_msg["Type"]=="Status":
            status_code=int(recv_msg["Content"].decode())
            if status_code==100:
                self.info("登陆成功")
            elif status_code==101:
                self.info("登陆失败:可能用户名或密码错误")
            elif status_code==102:
                self.info("没有登陆")
            elif status_code==103:
                self.info("已经存在登陆")
            elif status_code==200:
                self.info("注册成功")
            elif status_code==201:
                self.info("注册失败")
            elif status_code==300:
                self.info("发送成功")
            elif status_code==301:
                self.info(self.chatwith+"不在线")
            elif status_code==302:
                self.info("类型错误")
            elif status_code==303:
                self.info("没有文件名")
            elif status_code==400:
                self.info("注销成功")
            elif status_code==500:
                self.chatclient.disconnserver()
                self.chatclient=None
            elif status_code==600:
                self.info("获取好友列表失败")
            elif status_code==601:
                self.info("增加好友成功")
            elif status_code==602:
                self.info("增加好友失败")
            elif status_code==603:
                self.info("删除好友成功")
            elif status_code==604:
                self.info("删除好友失败")
        elif recv_msg["Type"]=="List":
            #print("好友数目",recv_msg["Count"])
            self.friends_list.delete(0,END)
            for friend in recv_msg["Content"].decode().split("\r\n"):
                #print("好友:",friend)
                self.friends_list.insert(END,friend)



    #chatclient info_event 事件处理函数
    def info(self,text):
        self.chatmessage_text.insert(END,text+"\n","information")

    #chatclient out_event事件处理函数
    def out(self,recv_msg):
        if recv_msg!=None:
            #显示接受数据在终端
            #print(recv_msg)
            self.parse(recv_msg)

if __name__=="__main__":

    MainWindow(sys.argv[1],sys.argv[2]).mainloop()




#! /usr/bin/python3.4
'''
    利用Tkinter,Socket,完成一个聊天软件开发
    主要目的作为Tkinter学习的实战训练

    自定义 chat 协议:
    From: 来自 服务器名为pchatsvr
    To: 目标
    Date: 时间  eg(20:11:11)
    Type: 发送内容类型:可选["Plain","File","Login","Outlogin","Register","Quit","Status","List","Add","Delete"]
    Length: [可选]内容长度, 好友数目时将使用Count,不适用Length
    Name:[可选]文件名
    Count:[可选]好友数
    //空行
    ......             主体内容

    状态码:
        100 登陆成功
        101 登陆失败
        102 没有登陆
        103 已经存在登陆
        200 注册成功
        201 注册失败
        300 发送消息成功
        301 To出错
        302 Type出错
        303 Name出错,当type为File时
        400 注销成功
        500 离开
        600 例举好友失败
        601 add好友成功
        602 add好友失败
        603 delete好友成功
        604 delete好友失败


'''
import socket
import select
import time
import sqlite3

#chat服务类
class ChatServer():
    def __init__(self):
        self.servername="pchatsvr"
        self.serverSock=socket.socket()
        self.serverSock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        self.usersdbname="users.db" #用户数据库
        self.users={}            #用户字典 只有登陆后才会添加 key用户名,value套接字
        self.sockets=[]        #套接字列表

        self.init_db() #初始化数据库

    def init_db(self):
        self.conn=sqlite3.connect(database=self.usersdbname)
        #用户表
        try:
            self.conn.execute("CREATE TABLE USERS(name VARCHAR(20) PRIMARY KEY,password VARCHAR(30) not null)")
        except BaseException as e:
            #print(e)
            pass
        #好友表
        try:
            self.conn.execute("CREATE TABLE FRIENDS(name_1 VARCHAR(20), name_2 VARCHAR(20),FOREIGN KEY(name_1) REFERENCES USERS(name),FOREIGN KEY(name_2) REFERENCES USERS(name))")
        except BaseException as e:
            #print(e)
            pass
    #关闭数据库
    def close_db(self):
        self.conn.close()
        self.conn=None
    #判断用户知否存在
    def has_user_db(self,name,pwd):
        try:
            r=self.conn.execute("SELECT COUNT(*) FROM USERS WHERE name='%s' AND password='%s'"%(name,pwd))
            for row in r:
                if row[0]>0:
                    return True
                else:
                    return False
        except BaseException as e:
            print(e)

    def add_user_db(self,name,pwd):
        if self.has_user_db(name,pwd):
            return False
        else:
            try:
                self.conn.execute("INSERT INTO USERS VALUES('%s','%s')"%(name,pwd))
                self.conn.commit()
                return True
            except:
                return False
    def friends_list_db(self,name):
        friends=[]
        try:
            res=self.conn.execute("SELECT name_2 FROM FRIENDS WHERE name_1='%s'"%(name))
            for row in res:
                friends.append(row[0])
            return friends
        except BaseException as e:
            #print(e)
            return None
    #增加好友
    def friend_add_db(self,name_1,name_2):
        try:
            self.conn.execute("INSERT INTO FRIENDS VALUES('%s','%s')"%(name_1,name_2))
            self.conn.commit()
            return True
        except:
            return False
    #删除好友
    def friend_delete_db(self,name_1,name_2):
        try:
            self.conn.execute("DELETE FROM FRIENDS WHERE name_1='%s' AND name_2='%s'"%(name_1,name_2))
            return True
        except:
            return False

    def start(self,hostname="",port=1234,listen_count=2):
            self.serverSock.bind((hostname,port))
            self.serverSock.listen(listen_count)
            self.sockets.append(self.serverSock)
            print("启动pchat服务监听")
            self.__run()

    def __select(self):
            #作出响应
            r_sockets=select.select(self.sockets,[],[])[0]
            for sock in r_sockets:
                #服务器套接字
                if sock==self.serverSock:
                    newsock,addr=self.serverSock.accept()
                    print("accept:",addr)
                    self.sockets.append(newsock)
                else:
                    recv_msg={}
                    fileobj=sock.makefile("rb",0)
                    while True:
                        try:
                            line=fileobj.readline()
                        except:
                            self.sockets.remove(sock)
                            sock.close()
                            return
                        if not len(line):
                            self.sockets.remove(sock)
                            sock.close()
                            return
                        if line==b"\r\n":
                            break
                        key,value=line.decode().strip().split(": ")
                        recv_msg[key]=value

                    length=int(recv_msg["Length"])
                    recv_msg["Content"]=b""
                    while length>0:
                        r=fileobj.read(min(length,1024))
                        if not len(r):
                            break
                        length-=len(r)
                        recv_msg["Content"]+=r
                    #print(recv_msg)
                    fileobj.close()

                    if recv_msg["Type"]=="Plain" or recv_msg["Type"]=="File":
                        if recv_msg["From"] not in self.users:
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"102")
                        elif recv_msg["To"] not in self.users:
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"301")
                        elif self.users[recv_msg["From"]]==sock:
                            if recv_msg["Type"]=="File" and "Name" not in recv_msg:
                                sock.send(("From: "+self.servername+"\r\n").encode())
                                sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                                t=time.localtime()
                                sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                                sock.send("Type: Status\r\n".encode())
                                sock.send("Length: 3\r\n".encode())
                                sock.send("\r\n".encode())
                                sock.send(b"303")
                            else:
                                sock.send(("From: "+self.servername+"\r\n").encode())
                                sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                                t=time.localtime()
                                sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                                sock.send("Type: Status\r\n".encode())
                                sock.send("Length: 3\r\n".encode())
                                sock.send("\r\n".encode())
                                sock.send(b"300")
                                #发送给聊天对象
                                chatwith_socket=self.users[recv_msg["To"]]
                                chatwith_socket.send(("From: "+recv_msg["From"]+"\r\n").encode())
                                chatwith_socket.send(("To: "+recv_msg["To"]+"\r\n").encode())
                                t=time.localtime()
                                chatwith_socket.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                                chatwith_socket.send(("Type: "+recv_msg["Type"]+"\r\n").encode())
                                chatwith_socket.send(("Length: "+recv_msg["Length"]+"\r\n").encode())
                                if "Name" in recv_msg:
                                    chatwith_socket.send(("Name: "+recv_msg["Name"]+"\r\n").encode())
                                chatwith_socket.send("\r\n".encode())
                                chatwith_socket.send(recv_msg["Content"])
                        else:
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"103")

                    elif recv_msg["Type"]=="Login":
                        name,pwd=recv_msg["Content"].decode().split("&")
                        if self.has_user_db(name,pwd):
                            #将用户加入users中
                            if name not in self.users:
                                self.users[name]=sock
                                sock.send(("From: "+self.servername+"\r\n").encode())
                                sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                                t=time.localtime()
                                sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                                sock.send("Type: Status\r\n".encode())
                                sock.send("Length: 3\r\n".encode())
                                sock.send("\r\n".encode())
                                sock.send(b"100")
                            else:
                                sock.send(("From: "+self.servername+"\r\n").encode())
                                sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                                t=time.localtime()
                                sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                                sock.send("Type: Status\r\n".encode())
                                sock.send("Length: 3\r\n".encode())
                                sock.send("\r\n".encode())
                                sock.send(b"103")
                        else:
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"101")

                    elif recv_msg["Type"]=="Register":
                        name,pwd=name,pwd=recv_msg["Content"].decode().split("&")
                        if self.add_user_db(name,pwd):
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"200")
                        else:
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"201")
                    elif recv_msg["Type"]=="Outlogin":
                        if recv_msg["From"] not in self.users:
                            #没有登陆
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"102")
                        elif self.users[recv_msg["From"]]==sock:
                            self.users.pop(recv_msg["From"])
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"400")
                        else:
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"103")

                    elif recv_msg["Type"]=="Quit":
                        if recv_msg["From"] in self.users and self.users[recv_msg["From"]]==sock:
                            self.users.pop(recv_msg["From"])
                        sock.send(("From: "+self.servername+"\r\n").encode())
                        sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                        t=time.localtime()
                        sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                        sock.send("Type: Status\r\n".encode())
                        sock.send("Length: 3\r\n".encode())
                        sock.send("\r\n".encode())
                        sock.send(b"500")
                        self.sockets.remove(sock)
                        sock.close()

                    elif recv_msg["Type"]=="List":
                        if not(recv_msg["From"] in self.users):
                            #没有登陆
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"102")
                        elif sock!=self.users[recv_msg["From"]]:
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"103")
                        else:
                            friends=self.friends_list_db(recv_msg["From"])
                            if friends==None:
                                sock.send(("From: "+self.servername+"\r\n").encode())
                                sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                                t=time.localtime()
                                sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                                sock.send("Type: Status\r\n".encode())
                                sock.send("Length: 3\r\n".encode())
                                sock.send("\r\n".encode())
                                sock.send(b"600")
                            else:
                                sock.send(("From: "+self.servername+"\r\n").encode())
                                sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                                t=time.localtime()
                                sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                                sock.send("Type: List\r\n".encode())
                                #sock.send("Length: \r\n".encode())
                                sock.send(("Count: "+str(len(friends))+"\r\n").encode())
                                sock.send("\r\n".encode())
                                for friend in friends:
                                    sock.send((friend+"\r\n").encode())

                    elif recv_msg["Type"]=="Add":
                        if not (recv_msg["From"] in self.users):
                            #没有登陆
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"102")
                        elif sock!=self.users[recv_msg["From"]]:
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"103")
                        else:
                            friend_name=recv_msg["Content"].decode()
                            if self.friend_add_db(recv_msg["From"],friend_name):
                                sock.send(("From: "+self.servername+"\r\n").encode())
                                sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                                t=time.localtime()
                                sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                                sock.send("Type: Status\r\n".encode())
                                sock.send("Length: 3\r\n".encode())
                                sock.send("\r\n".encode())
                                sock.send(b"601")
                            else:
                                sock.send(("From: "+self.servername+"\r\n").encode())
                                sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                                t=time.localtime()
                                sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                                sock.send("Type: Status\r\n".encode())
                                sock.send("Length: 3\r\n".encode())
                                sock.send("\r\n".encode())
                                sock.send(b"602")

                    elif recv_msg["Type"]=="Delete":
                        if not(recv_msg["From"] in self.users):
                            #没有登陆
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"102")
                        elif sock!=self.users[recv_msg["From"]]:
                            sock.send(("From: "+self.servername+"\r\n").encode())
                            sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                            t=time.localtime()
                            sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                            sock.send("Type: Status\r\n".encode())
                            sock.send("Length: 3\r\n".encode())
                            sock.send("\r\n".encode())
                            sock.send(b"103")
                        else:
                            friend_name=recv_msg["Content"].decode()
                            if self.friend_delete_db(recv_msg["From"],friend_name):
                                sock.send(("From: "+self.servername+"\r\n").encode())
                                sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                                t=time.localtime()
                                sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                                sock.sezhaond("Type: Status\r\n".encode())
                                sock.send("Length: 3\r\n".encode())
                                sock.send("\r\n".encode())
                                sock.send(b"603")
                            else:
                                sock.send(("From: "+self.servername+"\r\n").encode())
                                sock.send(("To: "+recv_msg["From"]+"\r\n").encode())
                                t=time.localtime()
                                sock.send(("Date: "+"%d:%d:%d"%(t.tm_hour,t.tm_min,t.tm_sec)+"\r\n").encode())
                                sock.send("Type: Status\r\n".encode())
                                sock.send("Length: 3\r\n".encode())
                                sock.send("\r\n".encode())
                                sock.send(b"604")

    def __run(self):
        while True:
            try:
                self.__select()
            except KeyboardInterrupt as e:
                self.close_db()
                print("关闭pchat服务")
                break

if __name__=="__main__":
    ChatServer().start()




'''
    自己实现popen和system,学习fork dup pipe exec 等等内容。
'''
import os

#采用双管道实现popen:dopen 这是HTTP中CGI的核心内容
def dopen(command):
    f_read,s_write=os.pipe()
    s_read,f_write=os.pipe()
    spid=os.fork()
    if spid<0:
        return -1,-1
    elif spid==0:
        os.close(f_read)
        os.close(f_write)
        os.dup2(s_read,0)
        os.dup2(s_write,1)
        command_list=command.split(" ")
        os.execv(command_list[0],command_list)
    else:
        os.close(s_read)
        os.close(s_write)
        return f_read,f_write
#模拟os.popen
def popen(command):
    #创建管道
    read_p,write_p=os.pipe()
    spid=os.fork()
    if spid<0:
        return -1
    elif spid==0:
        #子进程
        #关闭读端口
        os.close(read_p)
        os.dup2(write_p,1)
        command_list=command.split(" ")
        #替换子进程
        os.execv(command_list[0],command_list)
    else:
        #父进程
        os.close(write_p)
        #返回管道读端
        return read_p
#模拟os.system
def system(command):
    spid=os.fork()
    if spid<0:
        return -1
    elif spid==0:
        command_list=command.split(" ")
        os.execv(command_list[0],command_list)
    else:
        pass


if __name__=="__main__":
    #dopen测试
    r,w=dopen("/usr/bin/python3.4 test.py")
    os.write(w,"hello world\n".encode())
    while r>0:
        content=os.read(r,1024)
        if not len(content):
            break
        print(content.decode(),end="")
    os.close(r)
    #system测试#system("/usr/bin/xdg-open /home/qin/Documents/chat/chatclient.py")

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值