亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Python > 正文

基于python實現聊天室程序

2020-02-15 22:17:36
字體:
來源:轉載
供稿:網友

本文實例為大家分享了python實現簡單聊天室的具體代碼,供大家參考,具體內容如下

剛剛接觸python編程,又從接觸java開始一直對socket模塊感興趣,所以就做了一個聊天室的小程序。

該程序由客戶端與服務器構成,使用UDP服務,服務器端綁定本地IP和端口,客戶端由系統隨機選擇端口。

實現了群發、私發、點對點文件互傳功能。

客戶端自建了一個類繼承了Cmd模塊,使用自定義的命令command進行操作,調用相應的do_command方法。

使用json模塊進行消息的封裝序列化,在接收方進行解析。

客戶端代碼如下:

import socketimport threadingimport jsonimport osfrom cmd import Cmd  class Client(Cmd):  """  客戶端  """  prompt = '>>>'  intro = '[Welcome] 簡易聊天室客戶端(Cli版)/n' + '[Welcome] 輸入help來獲取幫助/n'  buffersize = 1024   def __init__(self, host):    """    構造    """    super().__init__()    self.__socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    # self.__id = None    self.__nickname = None    self.__host = host    self.thread_recv = None    self.threadisalive = False    # 是否在接收文件    self.recvfile = False    # 是否在發送文件    self.sendfile = False    self.filesize = None    self.sendfilesize = None     # 接收文件包計數    self.filecount = None    # 接收文件名    self.filename = None    # 發送文件名    self.sendfilename = None     # 發送者    self.filefrom = None    # 接收者    self.fileto = None     # 接收文件流    self.file_recv = None    # 發送文件流    self.file_send = None     # 接收文件地址    self.filefrom_addr = None    # 發送文件地址    self.fileto_addr = None   def __receive_message_thread(self):    """    接受消息線程    """    while self.threadisalive:      # noinspection PyBroadException      try:        buffer, addr = self.__socket.recvfrom(1024)        '''        文件流由發送端直接發送,不經過服務器,故當發送端發來的消息時,將收到的數據存入文件        '''        if (addr != self.__host) & (addr == self.filefrom_addr) & self.recvfile:          self.file_recv.write(buffer)          self.filecount += 1          if self.filecount * 1024 >= self.filesize:            self.file_recv.close()            print(self.filename, 'is received.')            self.recvfile = False          continue         js = json.loads(buffer.decode())         # 若接收的數據為消息信息,則顯示        if js['type'] == 'message':          print(js['message'])         # 若接收的數據為文件發送請求,則存儲文件信息,并顯示        elif js['type'] == 'filequest':          if self.recvfile:            self.__socket.sendto(json.dumps({              'type': 'fileres',              'fileres': 'no',              'nickname': self.__nickname,              'who': js['nickname'],              'errormessage': 'is transfroming files.',            }).encode(), self.__host)            continue          filename = js['filename']          who = js['nickname']          filesize = js['filesize']          self.recvfile = True          self.filesize = filesize          self.filename = filename          self.filecount = 0          self.filefrom = who          self.filefrom_addr = (js['send_ip'], js['send_port'])           print('[system]:', who, ' send a file(',             filename, ') to you. receive? ')         # 接受的數據為請求回復,若同意接收則存儲服務器發來的接收方的地址,并開啟發送線程        elif js['type'] == 'fileres':          if js['fileres'] == 'yes':            print(js['recv_ip'], js['recv_port'])            self.fileto_addr = (js['recv_ip'], js['recv_port'])            thread = threading.Thread(              target=self.__send_file_thread)            thread.start()          else:            print(js['nickname'], js['errormessage'])            self.sendfile = False       except Exception as e:        print(e)        print('[Client] 無法從服務器獲取數據')   def __send_broadcast_message_thread(self, message):    """    發送廣播消息線程    :param message: 消息內容    """    self.__socket.sendto(json.dumps({      'type': 'broadcast',      'nickname': self.__nickname,      'message': message,    }).encode(), self.__host)   def __send_file_thread(self):    """    發送文件線程    :param message: 消息內容    """    filecount = 0    print('[system]', 'sending the file...')    while filecount * 1024 <= self.sendfilesize:      self.__socket.sendto(        self.file_send.read(1024), self.fileto_addr)      filecount += 1    self.file_send.close()    self.sendfile = False    print('[system]', 'the file is sended.')   def __send_whisper_message_thread(self, who, message):    """    發送私發消息線程    :param message: 消息內容    """    self.__socket.sendto(json.dumps({      'type': 'sendto',      'who': who,      'nickname': self.__nickname,      'message': message    }).encode(), self.__host)   def send_exit(self):    self.__socket.sendto(json.dumps({      'type': 'offline',      'nickname': self.__nickname,    }).encode(), self.__host)    def start(self):    """    啟動客戶端    """    self.cmdloop()   def do_login(self, args):    """    登錄聊天室    :param args: 參數    """    nickname = args.split(' ')[0]     # 將昵稱發送給服務器,獲取用戶id    self.__socket.sendto(json.dumps({      'type': 'login',      'nickname': nickname,    }).encode(), self.__host)    # 嘗試接受數據     buffer = self.__socket.recvfrom(1300)[0].decode()    obj = json.loads(buffer)    if obj['login'] == 'success':      self.__nickname = nickname      print('[Client] 成功登錄到聊天室')      self.threadisalive = True      # 開啟子線程用于接受數據      self.thread_recv = threading.Thread(        target=self.__receive_message_thread)      self.thread_recv.setDaemon(True)      self.thread_recv.start()    else:      print('[Client] 無法登錄到聊天室', obj['errormessage'])   def do_send(self, args):    """    發送消息    :param args: 參數    """    if self.__nickname is None:      print('請先登錄!login nickname')      return    message = args    # 開啟子線程用于發送數據    thread = threading.Thread(      target=self.__send_broadcast_message_thread, args=(message, ))    thread.setDaemon(True)    thread.start()   def do_sendto(self, args):    """    發送私發消息    :param args: 參數    """    if self.__nickname is None:      print('請先登錄!login nickname')      return    who = args.split(' ')[0]    message = args.split(' ')[1]    # # 顯示自己發送的消息    # print('[' + str(self.__nickname) + '(' + str(self.__id) + ')' + ']', message)    # 開啟子線程用于發送數據    thread = threading.Thread(      target=self.__send_whisper_message_thread, args=(who, message))    thread.setDaemon(True)    thread.start()   def do_catusers(self, arg):    if self.__nickname is None:      print('請先登錄!login nickname')      return    catmessage = json.dumps({'type': 'catusers'})    self.__socket.sendto(catmessage.encode(), self.__host)   def do_catip(self, args):    if self.__nickname is None:      print('請先登錄!login nickname')      return    who = args    catipmessage = json.dumps({'type': 'catip', 'who': who})    self.__socket.sendto(catipmessage.encode(), self.__host)   def do_help(self, arg):    """    幫助    :param arg: 參數    """    command = arg.split(' ')[0]    if command == '':      print('[Help] login nickname - 登錄到聊天室,nickname是你選擇的昵稱')      print('[Help] send message - 發送消息,message是你輸入的消息')      print('[Help] sendto who message - 私發消息,who是用戶名,message是你輸入的消息')      print('[Help] catusers - 查看所有用戶')      print('[Help] catip who - 查看用戶IP,who為用戶名')      print('[Help] sendfile who filedir - 向某用戶發送文件,who為用戶名,filedir為文件路徑')      print('[Help] getfile filename who yes/no - 接收文件,filename 為文件名,who為發送者,yes/no為是否接收')    elif command == 'login':      print('[Help] login nickname - 登錄到聊天室,nickname是你選擇的昵稱')    elif command == 'send':      print('[Help] send message - 發送消息,message是你輸入的消息')    elif command == 'sendto':      print('[Help] sendto who message - 發送私發消息,message是你輸入的消息')    else:      print('[Help] 沒有查詢到你想要了解的指令')   def do_exit(self, arg): # 以do_*開頭為命令    print("Exit")    self.send_exit()    try:      self.threadisalive = False      self.thread_recv.join()    except Exception as e:      print(e)    # self.__socket.close()   def do_sendfile(self, args):    who = args.split(' ')[0]    filepath = args.split(' ')[1]    filename = filepath.split('//')[-1]    # 判斷是否在發送文件    if self.sendfile:      print('you are sending files, please try later.')      return    if not os.path.exists(filepath):      print('the file is not exist.')      return    filesize = os.path.getsize(filepath)    # print(who, filename, filesize)     self.sendfile = True    self.fileto = who    self.sendfilename = filename    self.sendfilesize = filesize    self.file_send = open(filepath, 'rb')     self.__socket.sendto(json.dumps({      'type': 'filequest',      'nickname': self.__nickname,      'filename': self.sendfilename,      'filesize': self.sendfilesize,      'who': self.fileto,      'send_ip': '',      'send_port': '',    }).encode(), self.__host)     print('request send...')     # fileres = self.__socket.recvfrom(1024)[0].decode()    # js = json.loads(fileres)   def do_getfile(self, args):    filename = args.split(' ')[0]    who = args.split(' ')[1]    ch = args.split(' ')[2]    # print(self.filename is not None, filename, self.filename, who, self.filefrom)    if (self.filename is not None) & (filename == self.filename) & (who == self.filefrom):      if ch == 'yes':        self.file_recv = open(self.filename, 'wb')        self.__socket.sendto(json.dumps({          'type': 'fileres',          'fileres': 'yes',          'nickname': self.__nickname,          'who': who,          'recv_ip': '',          'recv_port': '',        }).encode(), self.__host)        print('you agree to reveive the file(', filename, ') from', who)       else:        self.__socket.sendto(json.dumps({          'type': 'fileres',          'fileres': 'no',          'nickname': self.__nickname,          'errormessage': 'deny the file.',          'who': who,          'recv_ip': '',          'recv_port': '',        }).encode(), self.__host)        print('you deny to reveive the file(', filename, ') from', who)        self.recvfile = False    else:      print('the name or sender of the file is wrong.')  c = Client(('127.0.0.1', 12346))c.start()            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日韩国产成人在线| 国产精品成人观看视频国产奇米| 亚洲区在线播放| 亚洲人成电影网站色| 国语自产精品视频在线看一大j8| 日韩有码在线观看| 国产成人免费91av在线| 亚洲永久在线观看| 美日韩丰满少妇在线观看| 国产精品电影在线观看| 精品成人国产在线观看男人呻吟| 欧美黑人极品猛少妇色xxxxx| 久久久精品一区| 日韩欧美在线视频| 日韩av综合网站| www日韩欧美| 中文字幕在线日韩| 日韩av电影手机在线| 亚洲精品国产福利| 日本精品在线视频| 日韩av日韩在线观看| 一本色道久久88综合日韩精品| 国产精品视频最多的网站| 91精品国产91久久久久久久久| 91精品国产91久久| 亚洲一区二区三区在线免费观看| 欧美洲成人男女午夜视频| 91日本在线观看| 91免费视频网站| 成人网在线免费看| 国产精品丝袜视频| 久久91超碰青草是什么| 欧美风情在线观看| 亚洲男人天堂网站| 九九热在线精品视频| 色综合老司机第九色激情| 2020久久国产精品| 91po在线观看91精品国产性色| 久久久人成影片一区二区三区观看| 久久精品国产96久久久香蕉| 国产91在线播放九色快色| 91精品国产高清久久久久久91| 久久综合免费视频| 精品色蜜蜜精品视频在线观看| 日韩免费在线视频| 青青在线视频一区二区三区| 美女少妇精品视频| 97精品在线视频| 精品一区二区三区四区在线| 91精品综合久久久久久五月天| 日韩女优人人人人射在线视频| 91夜夜揉人人捏人人添红杏| 疯狂欧美牲乱大交777| 亚洲一区免费网站| 国产精品大陆在线观看| 亚洲性无码av在线| 国产精品亚洲视频在线观看| 欧美成人黄色小视频| 欧美日韩免费网站| 欧美激情欧美激情| 欧美高清无遮挡| 色噜噜国产精品视频一区二区| 亚洲国产中文字幕久久网| 亚洲福利视频专区| 91沈先生在线观看| 亚洲精品按摩视频| 亚洲国产又黄又爽女人高潮的| 国产精品网站入口| 欧美男插女视频| 亚洲精品小视频在线观看| 91精品国产91久久久久久久久| 精品毛片三在线观看| xvideos国产精品| 91精品啪aⅴ在线观看国产| 日韩欧美一区视频| 国产精品久久久久久影视| 这里只有视频精品| 亚洲激情视频在线观看| 日韩激情视频在线播放| 欧美乱大交做爰xxxⅹ性3| 日韩精品视频在线播放| 亚洲精品第一页| 久久亚洲私人国产精品va| 国产精品激情自拍| 欧美成人午夜视频| 色综合天天狠天天透天天伊人| 大桥未久av一区二区三区| 久久九九精品99国产精品| 91精品国产自产91精品| 欧美在线免费视频| 伊人一区二区三区久久精品| 成人免费网站在线看| 午夜精品一区二区三区在线视| 国产精品91免费在线| 久久久在线视频| 国产精品激情av电影在线观看| 久久精品美女视频网站| 成人欧美在线观看| 狠狠干狠狠久久| 最近日韩中文字幕中文| 欧美激情久久久久| 国产精品va在线播放我和闺蜜| 国产欧美一区二区三区久久人妖| 欧美黄网免费在线观看| 高清亚洲成在人网站天堂| 国产日韩在线看片| 国产欧洲精品视频| 国产亚洲欧美日韩一区二区| 亚洲在线第一页| 国产成人自拍视频在线观看| 欧美又大又硬又粗bbbbb| 国产主播欧美精品| 亚洲国产精久久久久久| 国产日韩精品视频| 日韩av免费看网站| 欧美日韩在线观看视频小说| 欧美成人黑人xx视频免费观看| 欧美成人一二三| 2019最新中文字幕| 91美女片黄在线观| 美日韩丰满少妇在线观看| 色婷婷久久av| 欧美网站在线观看| 国产精品视频专区| 国产亚洲欧美日韩精品| 国产午夜精品美女视频明星a级| 亚洲国产精品电影| 亚洲成avwww人| 欧美丰满片xxx777| 最近2019年中文视频免费在线观看| 色香阁99久久精品久久久| 欧美一区第一页| 美女视频黄免费的亚洲男人天堂| 91免费视频国产| 亚洲精品福利免费在线观看| 色爱精品视频一区| 欧美极品欧美精品欧美视频| 最近中文字幕日韩精品| 国产精品欧美在线| 欧美风情在线观看| 97福利一区二区| 777午夜精品福利在线观看| 亚洲小视频在线| 国产精品青青在线观看爽香蕉| 亚洲精品99久久久久| 啊v视频在线一区二区三区| 欧美激情亚洲综合一区| 一区二区欧美激情| 国产精品青青在线观看爽香蕉| 精品欧美激情精品一区| 精品福利在线视频| 亚洲性生活视频在线观看| 精品av在线播放| 久久久久久这里只有精品| 日韩av在线播放资源| 伊人久久久久久久久久久久久| 亚洲成人精品久久久| 国产精品久久9| 久久国产精品影片| 欧美综合第一页| 92裸体在线视频网站| 人人做人人澡人人爽欧美| 日韩精品在线免费播放| 成人福利网站在线观看|