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 相关文章推荐
举例讲解Python设计模式编程中的访问者与观察者模式
Jan 26 Python
Django自定义认证方式用法示例
Jun 23 Python
Python 编码规范(Google Python Style Guide)
May 05 Python
用python实现刷点击率的示例代码
Feb 21 Python
python3实现二叉树的遍历与递归算法解析(小结)
Jul 03 Python
python读取多层嵌套文件夹中的文件实例
Feb 27 Python
PyQt5+Pycharm安装和配置图文教程详解
Mar 24 Python
python中二分查找法的实现方法
Dec 06 Python
Python数据分析库pandas高级接口dt的使用详解
Dec 11 Python
Python使用Opencv实现边缘检测以及轮廓检测的实现
Dec 31 Python
Python必备技巧之字符数据操作详解
Mar 23 Python
python 单机五子棋对战游戏
Apr 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
《雄兵连》《烈阳天道》真的来了
2020/07/13 国漫
PHP 数据库树的遍历方法
2009/02/06 PHP
ThinkPHP3.1新特性之内容解析输出详解
2014/06/19 PHP
PHP异常处理Exception类
2015/12/11 PHP
php获得文件夹下所有文件的递归算法的简单实例
2016/11/01 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
PHP实现负载均衡下的session共用功能
2018/04/17 PHP
PHP pthreads v3下的Volatile简介与使用方法示例
2020/02/21 PHP
IE无法设置短域名下Cookie
2010/09/23 Javascript
JQuery入门—编写一个简单的JQuery应用案例
2013/01/03 Javascript
给超链接添加特效鼠标移动展示提示信息且随鼠标移动
2013/10/17 Javascript
NodeJS制作爬虫全过程(续)
2014/12/22 NodeJs
jQuery视差滚动效果网页实现方法经验总结
2016/09/29 Javascript
原生javascript实现图片放大镜效果
2017/01/18 Javascript
微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传
2017/04/18 Javascript
微信小程序收藏功能的实现代码
2018/06/12 Javascript
使用vue的transition完成滑动过渡的示例代码
2018/06/25 Javascript
VueJS 取得 URL 参数值的方法
2019/07/19 Javascript
js实现聊天对话框
2020/02/08 Javascript
vue 路由守卫(导航守卫)及其具体使用
2020/02/25 Javascript
Vue 同步异步存值取值实现案例
2020/08/05 Javascript
vue3.0实现点击切换验证码(组件)及校验
2020/11/18 Vue.js
python如何使用unittest测试接口
2018/04/04 Python
不归路系列:Python入门之旅-一定要注意缩进!!!(推荐)
2019/04/16 Python
python实现五子棋游戏
2019/06/18 Python
美国派对用品及装饰品网上商店:Shindigz
2016/07/30 全球购物
惠普美国官方商店:HP Official Store
2016/08/28 全球购物
中国高端家电购物商城:顺电
2018/03/04 全球购物
英国在线潜水商店:Simply Scuba
2019/03/25 全球购物
数据库专业英语
2012/11/30 面试题
多媒体教室标语
2014/06/26 职场文书
法英专业大学生职业生涯规划范文:衡外情,量己力!
2014/09/23 职场文书
2014年小学图书室工作总结
2014/12/09 职场文书
营业员岗位职责
2015/02/11 职场文书
《丑小鸭》教学反思
2016/02/19 职场文书
Three.js实现雪糕地球的使用示例详解
2022/07/07 Javascript