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 相关文章推荐
可用于监控 mysql Master Slave 状态的python代码
Feb 10 Python
详解Python的Django框架中的templates设置
May 11 Python
python中实现延时回调普通函数示例代码
Sep 08 Python
解决pandas.DataFrame.fillna 填充Nan失败的问题
Nov 06 Python
在Pandas中给多层索引降级的方法
Nov 16 Python
python logging日志模块原理及操作解析
Oct 12 Python
pycharm激活码有效到2020年11月底
Sep 18 Python
Flask和pyecharts实现动态数据可视化
Feb 26 Python
解决numpy矩阵相减出现的负值自动转正值的问题
Jun 03 Python
python使用hdfs3模块对hdfs进行操作详解
Jun 06 Python
python b站视频下载的五种版本
May 27 Python
python单元测试之pytest的使用
Jun 07 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
新52大事件
2020/03/03 欧美动漫
PHP弹出提示框并跳转到新页面即重定向到新页面
2014/01/24 PHP
PHP批量删除、清除UTF-8文件BOM头的代码实例
2014/04/14 PHP
PHP+MySQL修改记录的方法
2015/01/21 PHP
分享一则PHP定义函数代码
2015/02/26 PHP
Yii框架数据模型的验证规则rules()被执行的方法
2016/12/02 PHP
基于swoole实现多人聊天室
2018/06/14 PHP
利用PHP如何统计Nginx日志的User Agent数据
2019/03/06 PHP
JavaScript 学习点滴记录
2009/04/24 Javascript
javascript 设置某DIV区域内的checkbox复选框
2009/11/30 Javascript
JQuery动态创建DOM、表单元素的实现代码
2011/08/09 Javascript
Struts2的s:radio标签使用及用jquery添加change事件
2013/04/08 Javascript
jquery中$(#form :input)与$(#form input)的区别
2014/08/18 Javascript
原生js结合html5制作简易的双色子游戏
2015/03/30 Javascript
浅谈jquery之on()绑定事件和off()解除绑定事件
2016/10/26 Javascript
bootstrap快速制作后台界面
2016/12/05 Javascript
js仿小米手机上下滑动效果
2017/02/05 Javascript
jQuery实现扑克正反面翻牌效果
2017/03/10 Javascript
微信小程序实现多个按钮toggle功能的实例
2017/06/13 Javascript
javascript流程控制语句集合
2017/09/18 Javascript
工作中常用到的ES6语法
2018/09/04 Javascript
在Python中用get()方法获取字典键值的教程
2015/05/21 Python
Python 使用PIL中的resize进行缩放的实例讲解
2018/08/03 Python
python数据批量写入ScrolledText的优化方法
2018/10/11 Python
python3.4控制用户输入与输出的方法
2018/10/17 Python
对python多线程中互斥锁Threading.Lock的简单应用详解
2019/01/11 Python
浅析python表达式4+0.5值的数据类型
2020/02/26 Python
python中pyqtgraph知识点总结
2021/01/26 Python
一款纯css3实现的竖形二级导航的实例教程
2014/12/11 HTML / CSS
华为旗下电子商务平台:华为商城
2016/08/06 全球购物
盛大二次面试题
2016/11/18 面试题
农场厂长岗位职责
2013/12/28 职场文书
计生专干事迹
2014/05/28 职场文书
护士2015年终工作总结
2015/04/29 职场文书
远程教育学习心得体会
2016/01/23 职场文书
新店开业策划方案怎么书写?
2019/07/05 职场文书