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实现服务器中只重载被修改的进程的方法
Apr 30 Python
Python使用ftplib实现简易FTP客户端的方法
Jun 03 Python
Python使用pyh生成HTML文档的方法示例
Mar 10 Python
Flask框架各种常见装饰器示例
Jul 17 Python
Python 利用pydub库操作音频文件的方法
Jan 09 Python
python找出列表中大于某个阈值的数据段示例
Nov 24 Python
Python拼接字符串的7种方式详解
Mar 19 Python
Python数据结构dict常用操作代码实例
Mar 12 Python
python编写俄罗斯方块
Mar 13 Python
解析Tensorflow之MNIST的使用
Jun 30 Python
Python 在函数上添加包装器
Jul 28 Python
Python Opencv图像处理基本操作代码详解
Aug 31 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/03/04 日漫
php获取表单中多个同名input元素的值
2014/03/20 PHP
php中header设置常见文件类型的content-type
2015/06/23 PHP
PHP下SSL加密解密、验证、签名方法(很简单)
2020/06/28 PHP
php编程每天必学之验证码
2016/03/03 PHP
详解在PHP的Yii框架中使用行为Behaviors的方法
2016/03/18 PHP
php字符串的替换,分割和连接方法
2016/05/23 PHP
php自定义函数实现二维数组排序功能
2016/07/20 PHP
php基于curl主动推送最新内容给百度收录的方法
2016/10/14 PHP
JavaScript入门教程(8) Location地址对象
2009/01/31 Javascript
Extjs学习笔记之五 一个小细节renderTo和applyTo的区别
2010/01/07 Javascript
浅析javascript闭包 实例分析
2010/12/25 Javascript
深入理解javascript中defer的作用
2013/12/11 Javascript
JavaScript中定义函数的三种方法
2015/03/12 Javascript
jQuery实现带水平滑杆的焦点图动画插件
2016/03/08 Javascript
Bootstrap组件学习之导航、标签、面包屑导航(精品)
2016/05/17 Javascript
bootstrap datepicker 与bootstrapValidator同时使用时选择日期后无法正常触发校验的解决思路
2016/09/28 Javascript
ES6学习教程之块级作用域详解
2017/10/09 Javascript
微信小程序canvas实现刮刮乐效果
2018/07/09 Javascript
vue实现前端分页完整代码
2020/06/17 Javascript
vue项目中使用多选框的实例代码
2020/07/22 Javascript
JavaScript语法约定和程序调试原理解析
2020/11/03 Javascript
Python使用bs4获取58同城城市分类的方法
2015/07/08 Python
简介Django框架中可使用的各类缓存
2015/07/23 Python
Python实现将Excel转换为json的方法示例
2017/08/05 Python
python3下使用cv2.imwrite存储带有中文路径图片的方法
2018/05/10 Python
pygame游戏之旅 按钮上添加文字的方法
2018/11/21 Python
python 消除 futureWarning问题的解决
2019/12/25 Python
详解Django中views数据查询使用locals()函数进行优化
2020/08/24 Python
Python classmethod装饰器原理及用法解析
2020/10/17 Python
Footshop乌克兰:运动鞋的最大选择
2019/12/01 全球购物
2014年预备党员端正入党动机思想汇报
2014/09/13 职场文书
工程部部长岗位职责
2015/02/12 职场文书
当幸福来敲门观后感
2015/06/01 职场文书
教师学期述职自我鉴定
2019/08/16 职场文书
教你使用pyinstaller打包Python教程
2021/05/27 Python