python实现socket+threading处理多连接的方法


Posted in Python onJuly 23, 2019

一.运行效果

先说两句,之前我在网上找的相关文章标题上写的是处理多连接,尼玛,全是假的。网上那些,根本不能异步处理多连接,不能主动给客户端发消息。

python实现socket+threading处理多连接的方法

在服务端控制台输入1,查看在线人数。

python实现socket+threading处理多连接的方法

给指定客户端发送消息。

python实现socket+threading处理多连接的方法

二.开发思路

以下说的是服务端开发思路,客户端比较简单就不说了。

首先,需要明白的是socket的accept和recv这两个方法是阻塞线程的。这就意味着我们需要新开线程来处理这两个方法。

具体的程序流程大概是这样的:

1.新开一个线程用于接收新的连接(socket.accept())

2.当有新的连接时,再新开一个线程,用于接收这个连接的消息(socket.recv())

3.主线程做为控制台,接收用户的输入,进行其他操作

也就是说,服务端需要为每一个连接创建一个线程。

三.服务端代码

全局部分的代码:

import socket # 导入 socket 模块
from threading import Thread
 
ADDRESS = ('127.0.0.1', 8712) # 绑定地址
 
g_socket_server = None # 负责监听的socket
 
g_conn_pool = [] # 连接池

其中,g_conn_pool是用来存放每一个客户端socket的。

初始化服务端:

def init():
  """
  初始化服务端
  """
  global g_socket_server
  g_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建 socket 对象
  g_socket_server.bind(ADDRESS)
  g_socket_server.listen(5) # 最大等待数(有很多人理解为最大连接数,其实是错误的)
  print("服务端已启动,等待客户端连接...")

socket.listen()的参数意义不要理解错了哦~

接收客户端连接和处理客户端消息:

def accept_client():
  """
  接收新连接
  """
  while True:
    client, _ = g_socket_server.accept() # 阻塞,等待客户端连接
    # 加入连接池
    g_conn_pool.append(client)
    # 给每个客户端创建一个独立的线程进行管理
    thread = Thread(target=message_handle, args=(client,))
    # 设置成守护线程
    thread.setDaemon(True)
    thread.start()
 
 
def message_handle(client):
  """
  消息处理
  """
  client.sendall("连接服务器成功!".encode(encoding='utf8'))
  while True:
    bytes = client.recv(1024)
    print("客户端消息:", bytes.decode(encoding='utf8'))
    if len(bytes) == 0:
      client.close()
      # 删除连接
      g_conn_pool.remove(client)
      print("有一个客户端下线了。")
      break

设置成守护线程的目的是为了防止主线程退出之后,程序进程不退出。

消息处理这一块,如果接收到一个长度为0的数据包,那么说明客户端掉线了。实际开发中,我们一般采用心跳包机制判断客户端是否在线。

最后,调用这些方法,让服务端启动:

if __name__ == '__main__':
  init()
  # 新开一个线程,用于接收新连接
  thread = Thread(target=accept_client)
  thread.setDaemon(True)
  thread.start()
  # 主线程逻辑
  while True:
    cmd = input("""--------------------------
输入1:查看当前在线人数
输入2:给指定客户端发送消息
输入3:关闭服务端
""")
    if cmd == '1':
      print("--------------------------")
      print("当前在线人数:", len(g_conn_pool))
    elif cmd == '2':
      print("--------------------------")
      index, msg = input("请输入“索引,消息”的形式:").split(",")
      g_conn_pool[int(index)].sendall(msg.encode(encoding='utf8'))
    elif cmd == '3':
      exit()

如果对流程不清楚的话,可以再回到上面,看看文章的第二部分。

四.客户端代码

客户端这部分设计的很简单。

import socket # 导入 socket 模块
 
s = socket.socket() # 创建 socket 对象
s.connect(('127.0.0.1', 8712))
print(s.recv(1024).decode(encoding='utf8'))
s.send("连接了".encode('utf8'))
print(s.recv(1024).decode(encoding='utf8'))
input("")

最后的input是为了阻塞线程,防止程序接收到消息之后就退出了。

以上这篇python实现socket+threading处理多连接的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Pthon批量处理将pdb文件生成dssp文件
Jun 21 Python
python机器学习实战之树回归详解
Dec 20 Python
Python中if elif else及缩进的使用简述
May 31 Python
selenium+python 对输入框的输入处理方法
Oct 11 Python
利用pyinstaller打包exe文件的基本教程
May 02 Python
Python collections中的双向队列deque简单介绍详解
Nov 04 Python
python中Lambda表达式详解
Nov 20 Python
django实现将修改好的新模型写入数据库
Mar 31 Python
查看已安装tensorflow版本的方法示例
Apr 19 Python
Python 通过正则表达式快速获取电影的下载地址
Aug 17 Python
详解anaconda离线安装pytorchGPU版
Sep 08 Python
python实现ping命令小程序
Dec 28 Python
简单了解Django ContentType内置组件
Jul 23 #Python
50行Python代码获取高考志愿信息的实现方法
Jul 23 #Python
python设计tcp数据包协议类的例子
Jul 23 #Python
Django 缓存配置Redis使用详解
Jul 23 #Python
Flask框架中request、请求钩子、上下文用法分析
Jul 23 #Python
python 的 scapy库,实现网卡收发包的例子
Jul 23 #Python
python3+django2开发一个简单的人员管理系统过程详解
Jul 23 #Python
You might like
全国FM电台频率大全 - 14 江西省
2020/03/11 无线电
PHP入门学习笔记之一
2010/10/12 PHP
PHP学习笔记之一
2011/01/17 PHP
php的webservice的wsdl的XML无法显示问题的解决方法
2014/03/11 PHP
PHP中cookie和session的区别实例分析
2014/08/28 PHP
ThinkPHP5 验证器的具体使用
2018/05/31 PHP
laravel 解决后端无法获取到前端Post过来的值问题
2019/10/22 PHP
JQUERY 对象与DOM对象之两者相互间的转换
2009/04/27 Javascript
Js四则运算函数代码
2012/07/21 Javascript
JavaScript判断DOM何时加载完毕的技巧
2012/11/11 Javascript
用javascript删除当前行,添加行(示例代码)
2013/11/25 Javascript
自定义百度分享的分享按钮
2015/03/18 Javascript
jquery用ajax方式从后台获取json数据后如何将内容填充到下拉列表
2015/08/26 Javascript
jquery trigger函数执行两次的解决方法
2016/02/29 Javascript
Js 获取当前函数参数对象的实现代码
2016/06/20 Javascript
jQuery加载及解析XML文件的方法实例分析
2017/01/22 Javascript
浅谈vue项目可以从哪些方面进行优化
2018/05/05 Javascript
JavaScript中的null和undefined用法解析
2019/09/30 Javascript
TensorFlow.js 微信小程序插件开始支持模型缓存的方法
2020/02/21 Javascript
PyCharm 设置SciView工具窗口的方法
2019/01/15 Python
Python开启线程,在函数中开线程的实例
2019/02/22 Python
Django集成CAS单点登录的方法示例
2019/06/10 Python
python判断一个对象是否可迭代的例子
2019/07/22 Python
Python 程序员必须掌握的日志记录
2020/08/17 Python
css3 线性渐变和径向渐变示例附图
2014/04/08 HTML / CSS
CSS3制作圆形滚动进度条动画的示例
2020/11/05 HTML / CSS
关于HTML5的安全问题开发人员需要牢记的
2012/06/21 HTML / CSS
印尼在线旅游门户网站:NusaTrip
2019/11/01 全球购物
英国健身专家:WIT Fitness
2021/02/09 全球购物
EJB3推出JPA的原因
2013/10/16 面试题
最新的大学生找工作自我评价
2013/09/29 职场文书
传播学毕业生求职信
2013/10/11 职场文书
酒店餐厅2014重阳节活动策划方案
2014/09/16 职场文书
mysql知识点整理
2021/04/05 MySQL
解决golang post文件时Content-Type出现的问题
2021/05/02 Golang
用python基于appium模块开发一个自动收取能量的小助手
2021/09/25 Python