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 相关文章推荐
基于scrapy实现的简单蜘蛛采集程序
Apr 17 Python
python实现ping的方法
Jul 06 Python
利用Python破解验证码实例详解
Dec 08 Python
python+pygame实现坦克大战小游戏的示例代码(可以自定义子弹速度)
Aug 11 Python
Python爬虫+tkinter界面实现历史天气查询的思路详解
Feb 22 Python
python openpyxl模块的使用详解
Feb 25 Python
解决Pytorch中关于model.eval的问题
May 22 Python
tensorflow中的数据类型dtype用法说明
May 26 Python
Python答题卡识别并给出分数的实现代码
Jun 22 Python
Python开发工具Pycharm的安装以及使用步骤总结
Jun 24 Python
Python pandas求方差和标准差的方法实例
Aug 04 Python
python lambda 表达式形式分析
Apr 03 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&&mysql)五
2006/10/09 PHP
Yii框架中 find findAll 查找出制定的字段的方法对比
2014/09/10 PHP
php实现字符串首字母转换成大写的方法
2015/03/17 PHP
thinkphp Apache配置重启Apache1 restart 出错解决办法
2017/02/15 PHP
laravel 多图上传及图片的存储例子
2019/10/14 PHP
js 表格隔行颜色
2009/12/02 Javascript
Javascript 获取链接(url)参数的方法[正则与截取字符串]
2010/02/09 Javascript
javaScript call 函数的用法说明
2010/04/09 Javascript
解析Javascript中难以理解的11个问题
2013/12/09 Javascript
js模拟C#中List的简单实例
2014/03/06 Javascript
jQuery聚合函数实例
2015/05/21 Javascript
Node.js的文件权限及读写flag详解
2016/10/11 Javascript
Vue.js实现简单ToDoList 前期准备(一)
2016/12/01 Javascript
jQuery中的一些小技巧
2017/01/18 Javascript
Vuex利用state保存新闻数据实例
2017/06/28 Javascript
VueJs 将接口用webpack代理到本地的方法
2017/11/27 Javascript
微信小程序支付功能 php后台对接完整代码分享
2018/06/12 Javascript
vue router 源码概览案例分析
2018/10/09 Javascript
Vue组件教程之Toast(Vue.extend 方式)详解
2019/01/27 Javascript
[02:30]DOTA2放量测试专访海涛:呼吁保护新手玩家
2013/08/26 DOTA
python使用xmlrpc实例讲解
2013/12/17 Python
python正则表达式re模块详细介绍
2014/05/29 Python
python下载文件记录黑名单的实现代码
2017/10/24 Python
django框架用户权限中的session缓存到redis中的方法
2019/08/06 Python
Python基于gevent实现高并发代码实例
2020/05/15 Python
如何基于Python Matplotlib实现网格动画
2020/07/20 Python
荷兰领先的百货商店:De Bijenkorf
2018/10/17 全球购物
英国探险旅游专家:Explore
2018/12/20 全球购物
澳大利亚手袋、珠宝和在线时尚精品店:The Way
2019/12/21 全球购物
武汉东之林科技有限公司机试
2013/09/17 面试题
网络公司美工设计工作个人的自我评价
2013/11/03 职场文书
中考标语大全
2014/06/05 职场文书
2014年团支部年度工作总结
2014/12/24 职场文书
婚礼父母致辞
2015/07/28 职场文书
Windows 11上手初体验:任务栏和开始菜单等迎来大改
2021/11/21 数码科技
django中websocket的具体使用
2022/01/22 Python