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对Csv文件操作实例代码
May 12 Python
PyQt5打开文件对话框QFileDialog实例代码
Feb 07 Python
python调用API实现智能回复机器人
Apr 10 Python
解决Python2.7读写文件中的中文乱码问题
Apr 12 Python
Python 经典面试题 21 道【不可错过】
Sep 21 Python
Python qqbot 实现qq机器人的示例代码
Jul 11 Python
python中的逆序遍历实例
Dec 25 Python
Python反爬虫伪装浏览器进行爬虫
Feb 28 Python
PyQt5如何将.ui文件转换为.py文件的实例代码
May 26 Python
python中二分查找法的实现方法
Dec 06 Python
python的setattr函数实例用法
Dec 16 Python
python实现简单的学生管理系统
Feb 22 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
利用phpexcel把excel导入数据库和数据库导出excel实现
2014/01/09 PHP
PHP 芝麻信用接入的注意事项
2016/12/01 PHP
腾讯的ip接口 方便获取当前用户的ip地理位置
2010/11/25 Javascript
JQuery页面的表格数据的增加与分页的实现
2013/12/10 Javascript
Jquery实现鼠标移动放大图片功能实例
2015/03/25 Javascript
AngularJS模块管理问题的非常规处理方法
2015/04/29 Javascript
一个仿微博登陆邮箱提示框js开发案例
2016/07/28 Javascript
通过bootstrap全面学习less
2016/11/09 Javascript
jQuery插件HighCharts绘制2D带Label的折线图效果示例【附demo源码下载】
2017/03/08 Javascript
angular $watch 一个变量的变化(实例讲解)
2017/08/02 Javascript
vue router仿天猫底部导航栏功能
2017/10/18 Javascript
详解Webstorm 新建.vue文件支持高亮vue语法和es6语法
2017/10/26 Javascript
深入koa-bodyparser原理解析
2019/01/16 Javascript
微信小程序中使用Async-await方法异步请求变为同步请求方法
2019/03/28 Javascript
js消除图片小游戏代码
2019/12/11 Javascript
python处理圆角图片、圆形图片的例子
2014/04/25 Python
Python的ORM框架SQLAlchemy入门教程
2014/04/28 Python
Python paramiko模块的使用示例
2018/04/11 Python
Python中类的创建和实例化操作示例
2019/02/27 Python
Django项目中添加ldap登陆认证功能的实现
2019/04/04 Python
Django 后台获取文件列表 InMemoryUploadedFile的例子
2019/08/07 Python
Python编程快速上手——Excel到CSV的转换程序案例分析
2020/02/28 Python
三步解决python PermissionError: [WinError 5]拒绝访问的情况
2020/04/22 Python
python中子类与父类的关系基础知识点
2021/02/02 Python
Python中全局变量和局部变量的理解与区别
2021/02/07 Python
GWT (Google Web Toolkit)有哪些主要的原件组成?
2015/06/08 面试题
高三历史教学反思
2014/01/09 职场文书
个人查摆剖析材料
2014/02/04 职场文书
团队精神口号
2014/06/06 职场文书
小学学校评估方案
2014/06/08 职场文书
法定代表人授权委托书范本
2014/10/07 职场文书
2014幼儿园小班工作总结
2014/11/10 职场文书
地震慰问信
2015/02/14 职场文书
家装业务员岗位职责
2015/04/03 职场文书
应届生们该怎么书写求职信?
2019/07/05 职场文书
Django与数据库交互的实现
2021/06/03 Python