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中的装饰器、闭包和functools的教程
Apr 02 Python
举例区分Python中的浅复制与深复制
Jul 02 Python
Windows中安装使用Virtualenv来创建独立Python环境
May 31 Python
Python使用正则表达式抓取网页图片的方法示例
Apr 21 Python
AI人工智能 Python实现人机对话
Nov 13 Python
windows 下python+numpy安装实用教程
Dec 23 Python
Python打开文件,将list、numpy数组内容写入txt文件中的方法
Oct 26 Python
Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现
Apr 22 Python
解决python父线程关闭后子线程不关闭问题
Apr 25 Python
Python爬虫实现百度翻译功能过程详解
May 29 Python
Jupyter notebook 不自动弹出网页的解决方案
May 21 Python
Python+tkinter实现高清图片保存
Mar 13 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
我的论坛源代码(四)
2006/10/09 PHP
php&mysql 日期操作小记
2012/02/27 PHP
基于curl数据采集之单页面并行采集函数get_htmls的使用
2013/04/28 PHP
PHP使用Pthread实现的多线程操作实例
2015/11/14 PHP
php执行多个存储过程的方法【基于thinkPHP】
2016/11/08 PHP
YII2.0框架行为(Behavior)深入详解
2019/07/26 PHP
清华大学出版的事半功倍系列 javascript全部源代码
2007/05/04 Javascript
一个js封装的不错的选项卡效果代码
2008/02/15 Javascript
jquery 入门教程 [翻译] 推荐
2009/08/17 Javascript
JavaScript中发布/订阅模式的简单实例
2014/11/05 Javascript
jQuery中:last-child选择器用法实例
2014/12/31 Javascript
JS组件Bootstrap实现下拉菜单效果代码
2016/04/26 Javascript
JS在Chrome浏览器中showModalDialog函数返回值为undefined的解决方法
2016/08/03 Javascript
理解 Node.js 事件驱动机制的原理
2017/08/16 Javascript
原生JS获取元素的位置与尺寸实现方法
2017/10/18 Javascript
微信小程序实现animation动画
2018/01/26 Javascript
vue+element实现表单校验功能
2019/05/20 Javascript
JavaScript从原型到原型链深入理解
2019/06/03 Javascript
layui+jquery支持IE8的表格分页方法
2019/09/28 jQuery
解决antd的Form组件setFieldsValue的警告问题
2020/10/29 Javascript
Python实现提取文章摘要的方法
2015/04/21 Python
Django中STATIC_ROOT和STATIC_URL及STATICFILES_DIRS浅析
2018/05/08 Python
python自动发送测试报告邮件功能的实现
2019/01/22 Python
基于python3 pyQt5 QtDesignner实现窗口化猜数字游戏功能
2019/07/15 Python
OpenCV+face++实现实时人脸识别解锁功能
2019/08/28 Python
Python新手如何理解循环加载模块
2020/05/29 Python
HTML5 Canvas旋转动画的2个代码例子(一个旋转的太极图效果)
2014/04/10 HTML / CSS
丝绸和人造花卉、植物和树木:Nearly Natural
2018/11/28 全球购物
大学应届生求职简历的自我评价
2013/10/08 职场文书
初二生物教学反思
2014/02/03 职场文书
商场消防演习方案
2014/02/12 职场文书
社区党风廉政建设调研报告
2015/01/01 职场文书
检讨书模板大全
2015/05/07 职场文书
维护民族团结心得体会2016
2016/01/15 职场文书
2016廉洁从业学习心得体会
2016/01/19 职场文书
浅谈Node的内存泄露问题
2022/05/06 NodeJs