侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

python实现简单聊天应用 python群聊和点对点均实现

Python  /  管理员 发布于 7年前   169

后续代码更新和功能添加会提交到个人github主页,有兴趣可以一起来完善!

如果只是拿过去运行看结果,请注意平台相关性以及python版本号,本示例开发运行平台为win7x86_64 pycharm community,python版本号为3.5!!!

TALK IS CHEAP, SHOW YOU MY CODE:

客户端

#coding:utf-8'''file:client.py.pydate:2017/9/11 11:01author:lockeyemail:[email protected]:win7.x86_64 pycharm python3desc:p2p communication clientside'''from socket import *import threading,sys,json,re#引入json模块主要是为了数据的封装传输,re的话是做一些合法性的验证HOST = '192.168.1.7'PORT=8022BUFSIZE = 1024 ##缓冲区大小 1KADDR = (HOST,PORT)myre = r"^[_a-zA-Z]\w{0,}"tcpCliSock = socket(AF_INET,SOCK_STREAM)#创建一个socket连接userAccount = None#用户登录标志,也用来记录登录的用户名称def register():#用户注册函数 print(""" Glad to have you a member of us! """) accout = input('Please input your account: ') if not re.findall(myre, accout):  print('Account illegal!')  return None password1 = input('Please input your password: ') password2 = input('Please confirm your password: ') if not (password1 and password1 == password2):  print('Password not illegal!')  return None global userAccount userAccount = accout regInfo = [accout,password1,'register'] datastr = json.dumps(regInfo) tcpCliSock.send(datastr.encode('utf-8')) data = tcpCliSock.recv(BUFSIZE) data = data.decode('utf-8') if data == '0':  print('Success to register!')  return True elif data == '1':  print('Failed to register, account existed!')  return False else:  print('Failed for exceptions!')  return Falsedef login():#用户登录函数 print(""" Welcome to login in! """) accout = input('Account: ') if not re.findall(myre, accout):  print('Account illegal!')  return None password = input('Password: ') if not password:  print('Password illegal!')  return None global userAccount userAccount = accout loginInfo = [accout, password,'login'] datastr = json.dumps(loginInfo) tcpCliSock.send(datastr.encode('utf-8')) data = tcpCliSock.recv(BUFSIZE) if data == '0':  print('Success to login!')  return True else:  print('Failed to login in(user not exist or username not match the password)!')  return Falsedef addGroup():#群组添加 groupname = input('Please input group name: ') if not re.findall(myre, groupname):  print('group name illegal!')  return None return groupnamedef chat(target):#进入聊天(群聊和点对点聊天可以选择) while True:  print('{} -> {}: '.format(userAccount,target))  msg = input()  if len(msg) > 0 and not msg in 'qQ':   if 'group' in target:    optype = 'cg'   else:    optype = 'cp'   dataObj = {'type': optype, 'to': target, 'msg': msg, 'froms': userAccount}   datastr = json.dumps(dataObj)   tcpCliSock.send(datastr.encode('utf-8'))   continue  elif msg in 'qQ':   break  else:   print('Send data illegal!')class inputdata(threading.Thread):#用户输入选择然后执行不同的功能程序 def run(self):  menu = """      (CP): Chat with individual      (CG): Chat with group member      (AG): Add a group      (EG): Enter a group      (H): For help menu      (Q): Quit the system      """  print(menu)  while True:   operation = input('Please input your operation("h" for help): ')   if operation in 'cPCPCpcp':   #进入个人聊天    target = input('Who would you like to chat with: ')    chat(target)    continue   if operation in 'cgCGCgcG':   #进入群聊    target = input('Which group would you like to chat with: ')    chat('group'+target)    continue   if operation in 'agAGAgaG':   #添加群组    groupName = addGroup()    if groupName:     dataObj = {'type': 'ag', 'groupName': groupName}     dataObj = json.dumps(dataObj)     tcpCliSock.send(dataObj.encode('utf-8'))    continue   if operation in 'egEGEgeG':   #入群    groupname = input('Please input group name fro entering: ')    if not re.findall(myre, groupname):     print('group name illegal!')     return None    dataObj = {'type': 'eg', 'groupName': 'group'+groupname}    dataObj = json.dumps(dataObj)    tcpCliSock.send(dataObj.encode('utf-8'))    continue   if operation in 'hH':    print(menu)    continue   if operation in 'qQ':    sys.exit(1)   else:    print('No such operation!')class getdata(threading.Thread):#接收数据线程 def run(self):  while True:   data = tcpCliSock.recv(BUFSIZE).decode('utf-8')   if data == '-1':    print('can not connect to target!')    continue   if data == 'ag0':    print('Group added!')    continue   if data == 'eg0':    print('Entered group!')    continue   if data == 'eg1':    print('Failed to enter group!')    continue   dataObj = json.loads(data)   if dataObj['type'] == 'cg':   #群组消息的格式定义    print('{}(from {})-> : {}'.format(dataObj['froms'], dataObj['to'], dataObj['msg']))   else:   #个人消息的格式定义    print('{} ->{} : {}'.format(dataObj['froms'], userAccount, dataObj['msg']))def main():  try:   tcpCliSock.connect(ADDR)   print('Connected with server')   while True:    loginorReg = input('(l)ogin or (r)egister a new account: ')    if loginorReg in 'lL':     log = login()     if log:      break    if loginorReg in 'rR':     reg = register()     if reg:      break   myinputd = inputdata()   mygetdata = getdata()   myinputd.start()   mygetdata.start()   myinputd.join()   mygetdata.join()  except Exception:   print('error')   tcpCliSock.close()   sys.exit()if __name__ == '__main__': main()

服务端

#coding:utf-8'''file:server.pydate:2017/9/11 14:43author:lockeyemail:[email protected]:win7.x86_64 pycharm python3desc:p2p communication serverside'''import socketserver,json,timeimport subprocessconnLst = []groupLst = []## 代号 地址和端口 连接对象#optype = {'ag':'group adding','cp':'chat with individual','cg':'chat with group'}class Connector(object): ##连接对象类 def __init__(self,account,password,addrPort,conObj):  self.account = account  self.password = password  self.addrPort = addrPort  self.conObj = conObjclass Group(object):#群组类 def __init__(self,groupname,groupOwner):  self.groupId = 'group'+str(len(groupLst)+1)  self.groupName = 'group'+groupname  self.groupOwner = groupOwner  self.createTime = time.time()  self.members=[groupOwner]class MyServer(socketserver.BaseRequestHandler): def handle(self):  print("got connection from",self.client_address)  userIn = False  global connLst  global groupLst  while not userIn:   conn = self.request   data = conn.recv(1024)   if not data:    continue   dataobj = json.loads(data.decode('utf-8'))   #如果连接客户端发送过来的信息格式是一个列表且注册标识为False时进行用户注册或者登陆   ret = '0'   if type(dataobj) == list and not userIn:    account = dataobj[0]    password = dataobj[1]    optype = dataobj[2]    existuser = False    if len(connLst) > 0:     for obj in connLst:      if obj.account == account:       existuser = True       if obj.password == password:        userIn = True        print('{} has logged in system({})'.format(account,self.client_address))        break    if optype == 'login' and (not userIn or not existuser):     ret = '1'     print('{} failed to logged in system({})'.format(account, self.client_address))    else:     if existuser:      ret = '1'      print('{} failed to register({}),account existed!'.format(account, self.client_address))     else:      try:       conObj = Connector(account,password,self.client_address,self.request)       connLst.append(conObj)       print('{} has registered to system({})'.format(account,self.client_address))       userIn = True      except:       print('%s failed to register for exception!'%account)       ret = '99'   conn.sendall(ret.encode('utf-8'))   if ret == '0':    break  while True:  #除登陆注册之外的请求的监听   conn = self.request   data = conn.recv(1024)   if not data:    continue   print(data)   dataobj = data.decode('utf-8')   dataobj = json.loads(dataobj)   if dataobj['type'] == 'ag' and userIn:   #如果判断用户操作请求类型为添加群组则进行以下操作    groupName = dataobj['groupName']    groupObj = Group(groupName,self.request)    groupLst.append(groupObj)    conn.sendall('ag0'.encode('utf-8'))    print('%s added'%groupName)    continue   if dataobj['type'] == 'eg' and userIn:   #入群操作    groupName = dataobj['groupName']    ret = 'eg1'    for group in groupLst:     if groupName == group.groupName:      group.members.append(self.request)      print('{} added into {}'.format(self.client_address,groupName))      ret = 'eg0'      break    conn.sendall(ret.encode('utf-8'))    continue   #客户端将数据发给服务器端然后由服务器转发给目标客户端   print('connLst',connLst)   print('grouplst',groupLst)   if len(connLst) > 1:    sendok = False    if dataobj['type'] == 'cg':    #群内广播(除发消息的人)     print('group',data)     for obj in groupLst:      if obj.groupName == dataobj['to']:       for user in obj.members:        if user != self.request:         user.sendall(data)    else:    #个人信息发送     for obj in connLst:      if dataobj['to'] == obj.account:       obj.conObj.sendall(data)       sendok = True     if sendok == False:      print('no target valid!')   else:    conn.sendall('-1'.encode('utf-8'))    continueif __name__ == '__main__': server = socketserver.ThreadingTCPServer(('192.168.1.7',8022),MyServer) print('waiting for connection...') server.serve_forever()

运行结果示例

服务端(记录着各客户端的操作):

客户端1:

有注册、建群、群聊、点对点聊天

客户端2:

客户端3:

要拷贝代码运行的话请注意平台(win7.x86_64)和python版本号(python3.5)!!!


  • 上一条:
    python实现八大排序算法(1)
    下一条:
    Python实现购物系统(示例讲解)
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(95个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客