python实现的简单点对点(p2p)聊

  • 2020 年 1 月 10 日
  • 筆記

点对点聊天首先是基于多线程的网络编程,其次就是将每一个连接都保存为一个具有独一属性的对象并添加到连接列表中,对于每一个连接对象发送过来的信息必须要包含主要的三项内容(from,to,messages),这样当信息发送到服务器之后服务器根据to的连接对象遍历连接列表找到目标对象将信息发送给目标,目标拿到信息后就知道是谁发过来的,然后根据id号码进行回复。。此实现将会继续完善,后续新加功能将会在我个人github主页展现

服务器端实现:

#coding:utf-8  '''  file:server.py  date:2017/9/10 12:43  author:lockey  email:[email protected]  platform:win7.x86_64 pycharm python3  desc:p2p communication serverside  '''  import socketserver,json  import subprocess    connLst = []  ##  连接列表,用来保存一个连接的信息(代号 地址和端口 连接对象)  class Connector(object):#连接对象类      def __init__(self,account,password,addrPort,conObj):          self.account = account          self.password = password          self.addrPort = addrPort          self.conObj = conObj        class MyServer(socketserver.BaseRequestHandler):        def handle(self):          print("got connection from",self.client_address)          register = False          while True:              conn = self.request              data = conn.recv(1024)              if not data:                  continue              dataobj = json.loads(data.decode('utf-8'))              #如果连接客户端发送过来的信息格式是一个列表且注册标识为False时进行用户注册              if type(dataobj) == list and not register:                  account = dataobj[0]                  password = dataobj[1]                  conObj = Connector(account,password,self.client_address,self.request)                  connLst.append(conObj)                  register = True                  continue              print(connLst)              #如果目标客户端在发送数据给目标客服端              if len(connLst) > 1 and type(dataobj) == dict:                  sendok = False                  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('nobody recevied!'.encode('utf-8'))                  continue    if __name__ == '__main__':      server = socketserver.ThreadingTCPServer(('192.168.1.4',8022),MyServer)      print('waiting for connection...')      server.serve_forever()

客户端实现:

#coding:utf-8  '''  file:client.py.py  date:2017/9/10 11:01  author:lockey  email:[email protected]  platform:win7.x86_64 pycharm python3  desc:p2p communication clientside  '''  from socket import *  import threading,sys,json,re    HOST = '192.168.1.4'  ##  PORT=8022  BUFSIZ = 1024  ##缓冲区大小  1K  ADDR = (HOST,PORT)    tcpCliSock = socket(AF_INET,SOCK_STREAM)  tcpCliSock.connect(ADDR)  userAccount = None  def register():      myre = r"^[_a-zA-Z]w{0,}"      #正则验证用户名是否合乎规范      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      return (accout,password1)    class inputdata(threading.Thread):      def run(self):          while True:              sendto = input('to>>:')              msg = input('msg>>:')              dataObj = {'to':sendto,'msg':msg,'froms':userAccount}              datastr = json.dumps(dataObj)              tcpCliSock.send(datastr.encode('utf-8'))      class getdata(threading.Thread):      def run(self):          while True:              data = tcpCliSock.recv(BUFSIZ)              dataObj = json.loads(data.decode('utf-8'))              print('{} -> {}'.format(dataObj['froms'],dataObj['msg']))      def main():      while True:          regInfo = register()          if  regInfo:              datastr = json.dumps(regInfo)              tcpCliSock.send(datastr.encode('utf-8'))              break      myinputd = inputdata()      mygetdata = getdata()      myinputd.start()      mygetdata.start()      myinputd.join()      mygetdata.join()      if __name__ == '__main__':      main()

运行结果示例:

服务器端结果:

客户端1:

客户端2:

客户端3:

如果运行出错请检查平台以及python版本号