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采用Django开发自己的博客系统
Sep 29 Python
分析Python读取文件时的路径问题
Feb 11 Python
使用pandas对两个dataframe进行join的实例
Jun 08 Python
解决python中画图时x,y轴名称出现中文乱码的问题
Jan 29 Python
python字符串循环左移
Mar 08 Python
python 实现的发送邮件模板【普通邮件、带附件、带图片邮件】
Jul 06 Python
Python 内置函数globals()和locals()对比详解
Dec 23 Python
详解python内置常用高阶函数(列出了5个常用的)
Feb 21 Python
如何基于python3和Vue实现AES数据加密
Mar 27 Python
python爬虫实现POST request payload形式的请求
Apr 30 Python
Python代码执行时间测量模块timeit用法解析
Jul 01 Python
整理Python中常用的conda命令操作
Jun 15 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中shuffle数组值随便排序函数用法
2014/11/21 PHP
在Mac OS上搭建Nginx+PHP+MySQL开发环境的教程
2015/12/21 PHP
PHP数据库连接mysql与mysqli对比分析
2016/01/04 PHP
PHP抓取及分析网页的方法详解
2016/04/26 PHP
使用jQuery操作Cookies的实现代码
2011/10/09 Javascript
使用npm发布Node.JS程序包教程
2015/03/02 Javascript
JavaScript实战之菜单特效
2016/08/16 Javascript
关于JavaScript数组你所不知道的3件事
2016/08/24 Javascript
JS实现颜色动态淡化效果
2017/03/06 Javascript
微信小程序 下拉菜单的实现
2017/04/06 Javascript
node.js 发布订阅模式的实例
2017/09/10 Javascript
javascript、php关键字搜索函数的使用方法
2018/05/29 Javascript
关于AngularJS中ng-repeat不更新视图的解决方法
2018/09/30 Javascript
微信小程序实现滑动切换自定义页码的方法分析
2018/12/29 Javascript
JS实现随机抽取三人
2019/11/06 Javascript
使用JavaScript和MQTT开发物联网应用示例解析
2020/08/07 Javascript
[02:16]DOTA2英雄基础教程 干扰者
2014/01/15 DOTA
python pdb调试方法分享
2014/01/21 Python
利用Fn.py库在Python中进行函数式编程
2015/04/22 Python
简单实现python爬虫功能
2015/12/31 Python
Python实现的序列化和反序列化二叉树算法示例
2019/03/02 Python
Django ImageFiled上传照片并显示的方法
2019/07/28 Python
Python学习笔记之Django创建第一个数据库模型的方法
2019/08/07 Python
用python生成与调用cntk模型代码演示方法
2019/08/26 Python
Python多线程模块Threading用法示例小结
2019/11/09 Python
Django对接支付宝实现支付宝充值金币功能示例
2019/12/17 Python
Python中pyecharts安装及安装失败的解决方法
2020/02/18 Python
JetBrains PyCharm(Community版本)的下载、安装和初步使用图文教程详解
2020/03/19 Python
Opencv常见图像格式Data Type及代码实例
2020/11/02 Python
Python爬虫新手入门之初学lxml库
2020/12/20 Python
Room Mate Hotels美国:西班牙酒店品牌
2018/04/10 全球购物
小学信息技术教学反思
2014/02/10 职场文书
核心价值观演讲稿
2014/05/13 职场文书
行政秘书工作自我鉴定
2014/09/15 职场文书
保险公司增员口号
2015/12/25 职场文书
JavaScript架构搭建前端监控如何采集异常数据
2022/06/25 Javascript