Python TCPServer 多线程多客户端通信的实现


Posted in Python onDecember 31, 2019

最简单、原始的TCP通信demo

服务端Http请求:

import socket

# 创建一个servicesocke
serviceSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 给服务器绑定地址(ip地址,端口号)
serviceSocket.bind(("192.168.171.1", 80))

print("等待客户端接入")
# sock 是客户端的socket信息
# addr 是客户端的地址(ip,端口)
sock, addr = serviceSocket.accept()
print(f"sock from client:{sock}")
print(f"addr of client:{addr}")

while True:
  # 接收客户端的请求
  recvData = sock.recv(1024)
  print("客户端说:%s" % (recvData.decode("utf-8")))
  sendData = input("服务器说:")
  # 发送(回复)数据给客户端
  sock.send(sendData.encode("utf-8"))

客户端Http请求:

import socket

# 创建客户端socket
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接服务器
clientSocket.connect(("192.168.171.1", 80))

while True:
  # 发送消息给服务器
  sendData = input("客户端说:")
  if sendData == "bye":
    clientSocket.send(sendData.encode("utf-8")) # 编码:将数据装换成二进制形式
    break
  clientSocket.send(sendData.encode("utf-8"))
  recvData = clientSocket.recv(1024)
  print("服务器说:%s" % (recvData.decode("utf-8"))) # 解码:将二进制转换成字符

1、在TCP中,客户端的实现流程:

创建客户端的socket对象建立与服务器之间的联系发送请求接收数据关闭连接

2、服务端的实现流程:

创建服务端的socket对象绑定服务端的地址设置监听器等待客户端的连接接收客户端的请求返回处理的结果到客户端

ThreadingTCPServer 多线程多客户端通信自动重连demo

socketserver继承图:

Python TCPServer 多线程多客户端通信的实现

TCPServer

# from socketserver import TCPServer, BaseRequestHandler, ThreadingTCPServer
from socketserver import TCPServer, StreamRequestHandler, ThreadingMixIn
import traceback

# class MyBaseRequestHandler(BaseRequestHandler):
class MyBaseRequestHandler(StreamRequestHandler):

  def handle(self):
    self.addr = self.request.getpeername()
    self.server.users[self.addr[1]] = self.request
    message = "IP " + self.addr[0] + ":" + str(self.addr[1]) + " Connected..."
    print(message)

    while True:
      try:
        data = self.request.recv(1024).decode('UTF-8', 'ignore').strip()
        print(f'receive from {self.client_address}:{data}')

        back_data = (f"response\"" + data + "\":\n").encode("utf8")
        self.request.sendall(back_data)
      except:
        traceback.print_exc()
        break

# 源码:class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
# 从ThreadingMixIn和TCPServer继承,实现多线程
class MyThreadingTCPServer(ThreadingMixIn, TCPServer):
  def __init__(self, server_address, RequestHandlerClass):
    TCPServer.__init__(self, server_address, RequestHandlerClass)
    self.users = {}


class MyTCPserver():
  def __init__(self, server_addr='192.168.1.109', server_port=23):
    self.server_address = server_addr
    self.server_port = server_port
    self.server_tuple = (self.server_address, self.server_port)

  def run(self):
    # server = TCPServer(self.server_tuple, MyBaseRequestHandler)
    server = MyThreadingTCPServer(self.server_tuple, MyBaseRequestHandler)
    server.serve_forever()


if __name__ == '__main__':
  myserver = MyTCPserver()
  myserver.run()

在telnet 下开启开启两个客户端,本电脑的IP为192.168.1.109,开两个客户端后,TCPServer的终端出现同一个IP但是不同端口的连接:

Python TCPServer 多线程多客户端通信的实现

TCPClient

import socket
import time

class MyClient:
  host = '192.168.1.109'
  port = 23
  bufsiz = 1024
  addr = None
  skt = None

  def __init__(self, host=None, port=None):
    if host != None:
      self.host = host

    if port != None:
      self.port = port

    if self.addr == None:
      self.addr = (self.host, self.port)

    self.doConnection()

  def doConnection(self):
    try:
      self.skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      self.skt.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
      print(self.addr)
      self.skt.connect(self.addr)
    except:
      pass

  def run(self):
    while True:
      try:
        _time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        self.skt.sendall(f'{_time}:i am clent1 '.encode('utf-8'))
        data = self.skt.recv(self.bufsiz)
        print(data.decode('utf-8', 'ignore'))
        if not data:
          break
        print(data.strip())
        time.sleep(5)
      except socket.error:
        print('socket error, reconnection') # 自动重连
        time.sleep(3)
        self.doConnection()
      except:
        print('other error')

    self.skt.close()


myclient = MyClient()
myclient.run()

上面用的是telnet工具来作为客户端,这里是用代码实现模拟的客户端。

Python TCPServer 多线程多客户端通信的实现

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
用smtplib和email封装python发送邮件模块类分享
Feb 17 Python
Python手机号码归属地查询代码
May 04 Python
Python3使用requests发闪存的方法
May 11 Python
PyQt5实现拖放功能
Apr 25 Python
Django框架设置cookies与获取cookies操作详解
May 27 Python
Python带参数的装饰器运行原理解析
Jun 09 Python
keras中的History对象用法
Jun 19 Python
python中Django文件上传方法详解
Aug 05 Python
python statsmodel的使用
Dec 21 Python
matplotlib相关系统目录获取方式小结
Feb 03 Python
Python中22个万用公式的小结
Jul 21 Python
python中filter,map,reduce的作用
Jun 10 Python
python给指定csv表格中的联系人群发邮件(带附件的邮件)
Dec 31 #Python
Python面向对象封装操作案例详解
Dec 31 #Python
Python实现隐马尔可夫模型的前向后向算法的示例代码
Dec 31 #Python
Python面向对象之私有属性和私有方法应用案例分析
Dec 31 #Python
Pycharm最新激活码2019(推荐)
Dec 31 #Python
python ftplib模块使用代码实例
Dec 31 #Python
深入了解如何基于Python读写Kafka
Dec 31 #Python
You might like
PHP写的获取各搜索蜘蛛爬行记录代码
2012/08/21 PHP
关于PHP堆栈与列队的学习
2013/06/21 PHP
简单实现php上传文件功能
2017/09/21 PHP
用倒置滤镜把div倒置,再把table倒置。
2007/07/31 Javascript
自己的js工具 Cookie 封装
2009/08/21 Javascript
JS 仿腾讯发表微博的效果代码
2013/12/25 Javascript
鼠标经过tr时,改变tr当前背景颜色
2014/01/13 Javascript
JS+CSS模拟可以无刷新显示内容的留言板实例
2015/03/03 Javascript
JavaScript实现随机替换图片的方法
2015/04/16 Javascript
jQuery移动web开发之页面跳转和加载外部页面的实现
2015/12/04 Javascript
全面解析jQuery $(document).ready()和JavaScript onload事件
2016/06/08 Javascript
node.js的事件机制
2017/02/08 Javascript
React Native使用fetch实现图片上传的示例代码
2018/03/07 Javascript
vue数组对象排序的实现代码
2018/06/20 Javascript
vue项目实现表单登录页保存账号和密码到cookie功能
2018/08/31 Javascript
React父子组件间的传值的方法
2018/11/13 Javascript
微信公众平台获取access_token的方法步骤
2019/03/29 Javascript
Vue实现计算器计算效果
2020/08/17 Javascript
Python爬虫DOTA排行榜爬取实例(分享)
2017/06/13 Python
详解Python列表赋值复制深拷贝及5种浅拷贝
2019/05/15 Python
整个世界的设计师家具在哈恩:Designathome
2019/03/25 全球购物
英国曼彻斯特宠物用品品牌:Bunty Pet Products
2019/07/27 全球购物
就业协议书怎么填
2014/04/11 职场文书
年度安全生产目标责任书
2014/07/23 职场文书
垃圾分类的活动方案
2014/08/15 职场文书
学校做一个有道德的人活动方案
2014/08/23 职场文书
婚前协议书标准版
2014/10/19 职场文书
2015年安全生产责任书
2015/01/30 职场文书
少年派的奇幻漂流观后感
2015/06/08 职场文书
污染环境建议书
2015/09/14 职场文书
2016年教师节特级教师获奖感言
2015/12/09 职场文书
SQL实现LeetCode(180.连续的数字)
2021/08/04 MySQL
使用GO语言实现Mysql数据库CURD的简单示例
2021/08/07 Golang
Pygame Event事件模块的详细示例
2021/11/17 Python
Javascript中Microtask和Macrotask鲜为人知的知识点
2022/04/02 Javascript
MYSQL如何查看操作日志详解
2022/05/30 MySQL