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 相关文章推荐
在Mac OS上部署Nginx和FastCGI以及Flask框架的教程
May 02 Python
python实现在windows服务中新建进程的方法
Jun 30 Python
Python监控主机是否存活并以邮件报警
Sep 22 Python
Python各类图像库的图片读写方式总结(推荐)
Feb 23 Python
简单实现python数独游戏
Mar 30 Python
通过Python 接口使用OpenCV的方法
Apr 02 Python
Python实现爬取马云的微博功能示例
Feb 16 Python
双向RNN:bidirectional_dynamic_rnn()函数的使用详解
Jan 20 Python
Keras 实现加载预训练模型并冻结网络的层
Jun 15 Python
python报错TypeError: ‘NoneType‘ object is not subscriptable的解决方法
Nov 05 Python
python基础详解之if循环语句
Apr 24 Python
Python编程super应用场景及示例解析
Oct 05 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 cout<<的一点看法
2010/01/24 PHP
PHP使用标准库spl实现的观察者模式示例
2018/08/04 PHP
用javascript获取textarea中的光标位置
2008/05/06 Javascript
Javascript之旅 对象的原型链之由来
2010/08/25 Javascript
js用Date对象处理时间实现思路及代码
2013/01/31 Javascript
js 浏览本地文件夹系统示例代码
2013/10/24 Javascript
jQuery实现网页抖动的菜单抖动效果
2015/08/07 Javascript
js自定义回调函数
2015/12/13 Javascript
JavaScript下的时间格式处理函数Date.prototype.format
2016/01/27 Javascript
JavaScript常用正则函数用法示例
2017/01/23 Javascript
js图片延迟加载(Lazyload)三种实现方式
2017/03/01 Javascript
JS动态添加的div点击跳转到另一页面实现代码
2017/09/30 Javascript
vue resource post请求时遇到的坑
2017/10/19 Javascript
jQuery内容过滤选择器与子元素过滤选择器用法实例分析
2019/02/20 jQuery
小程序:授权、登录、session_key、unionId的详解
2019/05/15 Javascript
在JavaScript中使用严格模式(Strict Mode)
2019/06/13 Javascript
微信小程序swiper禁止用户手动滑动代码实例
2019/08/23 Javascript
使用localStorage替代cookie做本地存储
2019/09/25 Javascript
使用kbone解决Vue项目同时支持小程序问题
2019/11/08 Javascript
解决ant design vue 表格a-table二次封装,slots渲染的问题
2020/10/28 Javascript
[58:12]Ti4第二日主赛事败者组 LGD vs iG 3
2014/07/21 DOTA
python实现向ppt文件里插入新幻灯片页面的方法
2015/04/28 Python
在Django的模板中使用认证数据的方法
2015/07/23 Python
Python random模块用法解析及简单示例
2017/12/18 Python
python tensorflow基于cnn实现手写数字识别
2018/01/01 Python
python实现全盘扫描搜索功能的方法
2019/02/14 Python
深入解析HTML5 Canvas控制图形矩阵变换的方法
2016/03/24 HTML / CSS
Canvas与图片压缩的示例代码
2017/11/28 HTML / CSS
Html5写一个简单的俄罗斯方块小游戏
2019/12/03 HTML / CSS
如何利用XMLHTTP检测URL及探测服务器信息
2013/11/10 面试题
解释下面关于J2EE的名词
2013/11/15 面试题
毕业留言寄语大全
2014/04/10 职场文书
大学新生军训方案
2014/05/03 职场文书
服务承诺书范文
2014/05/19 职场文书
科级干部群众路线教育实践活动对照检查材料思想汇报
2014/09/20 职场文书
Python写情书? 10行代码展示如何把情书写在她的照片里
2022/04/21 Python