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 相关文章推荐
使用Python3中的gettext模块翻译Python源码以支持多语言
Mar 31 Python
mysql 之通过配置文件链接数据库
Aug 12 Python
Python基础语言学习笔记总结(精华)
Nov 14 Python
Pytorch入门之mnist分类实例
Apr 14 Python
python实现扫描日志关键字的示例
Apr 28 Python
Python模拟登录的多种方法(四种)
Jun 01 Python
对PyTorch torch.stack的实例讲解
Jul 30 Python
从请求到响应过程中django都做了哪些处理
Aug 01 Python
pytorch动态网络以及权重共享实例
Jan 06 Python
python数字类型math库原理解析
Mar 02 Python
python 实现任务管理清单案例
Apr 25 Python
解决python3.x安装numpy成功但import出错的问题
Nov 17 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
一个PHP数组应该有多大的分析
2009/07/30 PHP
PHP 数组遍历顺序理解
2009/09/09 PHP
php使用CutyCapt实现网页截图保存的方法
2016/10/03 PHP
CI框架表单验证实例详解
2016/11/21 PHP
php框架CodeIgniter使用redis的方法分析
2018/04/13 PHP
yii2安装详细流程
2018/05/23 PHP
jquery ajax 同步异步的执行 return值不能取得的解决方案
2012/01/08 Javascript
jQuery下通过replace字符串替换实现大小图片切换
2012/05/22 Javascript
JS打开图片另存为对话框实现代码
2012/12/26 Javascript
jquery mobile动态添加元素之后不能正确渲染解决方法说明
2014/03/05 Javascript
用js判断输入是否为中文的函数
2014/03/10 Javascript
jQuery中prevUntil()方法用法实例
2015/01/08 Javascript
jQuery增加自定义函数的方法
2015/07/18 Javascript
Node.js与Sails ~项目结构与Mvc实现及日志机制
2015/10/14 Javascript
js运动应用实例解析
2015/12/28 Javascript
Angular.js与Bootstrap相结合实现手风琴菜单代码
2016/04/13 Javascript
jQuery实现简洁的轮播图效果实例
2016/09/07 Javascript
JS之获取样式的简单实现方法(推荐)
2016/09/13 Javascript
JavaScript中清空数组的三种方式
2017/03/22 Javascript
jQuery Ajax向服务端传递数组参数值的实例代码
2017/09/03 jQuery
angular.js和vue.js中实现函数去抖示例(debounce)
2018/01/18 Javascript
详解Angular调试技巧之报错404(not found)
2018/01/31 Javascript
vue插件实现v-model功能
2018/09/10 Javascript
手淘flexible.js框架使用和源代码讲解小结
2018/10/15 Javascript
JS+CSS实现随机点名(实例代码)
2019/11/04 Javascript
微信小程序自定义纯净模态框(弹出框)的实例代码
2020/03/09 Javascript
[00:35]TI7不朽珍藏III——寒冰飞龙不朽展示
2017/07/15 DOTA
Python pickle模块用法实例
2015/04/14 Python
Zooplus罗马尼亚:宠物食品和配件
2019/11/02 全球购物
白酒业务员岗位职责
2013/12/27 职场文书
就业协议书的作用
2014/04/11 职场文书
安全口号大全
2014/06/21 职场文书
2014年公务员转正工作总结
2014/11/07 职场文书
关于办理居住证的介绍信模板
2019/11/27 职场文书
python基础之类方法和静态方法
2021/10/24 Python
微软官方消息,在 2023 年 4 月 11 日之后微软将不再为 Office 2013 和 Skype for Business 2015 提供安全更新
2022/04/21 数码科技