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的for和break循环结构中使用else语句的技巧
May 24 Python
使用python实现ANN
Dec 20 Python
python TCP Socket的粘包和分包的处理详解
Feb 09 Python
Python程序运行原理图文解析
Feb 10 Python
python存储16bit和32bit图像的实例
Dec 05 Python
基于Django ORM、一对一、一对多、多对多的全面讲解
Jul 26 Python
pytorch构建多模型实例
Jan 15 Python
pytorch之Resize()函数具体使用详解
Feb 27 Python
基于matplotlib xticks用法详解
Apr 16 Python
Python Excel vlookup函数实现过程解析
Jun 22 Python
Python with语句用法原理详解
Jul 03 Python
2020年10款优秀的Python第三方库,看看有你中意的吗?
Jan 12 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分页类代码
2013/04/02 PHP
php实现遍历目录并删除指定文件中指定内容
2015/01/21 PHP
PHP递归创建多级目录
2015/11/05 PHP
使用ltrace工具跟踪PHP库函数调用的方法
2016/04/25 PHP
php实现留言板功能(代码详解)
2017/03/28 PHP
PHP实现找出有序数组中绝对值最小的数算法分析
2017/08/07 PHP
Thinkphp 在api开发中异常返回依然是html的解决方式
2019/10/16 PHP
javascript学习笔记(一) 在html中使用javascript
2012/06/18 Javascript
jquery删除指定的html标签并保留标签内文本内容的方法
2014/04/02 Javascript
JavaScript使用function定义对象并调用的方法
2015/03/23 Javascript
jQuery validate插件submitHandler提交导致死循环解决方法
2016/01/21 Javascript
js获取浏览器的各种属性
2017/04/27 Javascript
jQuery常用选择器详解
2017/07/17 jQuery
python实现2014火车票查询代码分享
2014/01/10 Python
python学习笔记:字典的使用示例详解
2014/06/13 Python
Python实现提取文章摘要的方法
2015/04/21 Python
Python函数中的函数(闭包)用法实例
2016/03/15 Python
Python基础教程之tcp socket编程详解及简单实例
2017/02/23 Python
Python复数属性和方法运算操作示例
2017/07/21 Python
python爬虫之BeautifulSoup 使用select方法详解
2017/10/23 Python
Python3实现的Mysql数据库操作封装类
2018/06/06 Python
pytorch制作自己的LMDB数据操作示例
2019/12/18 Python
python两个_多个字典合并相加的实例代码
2019/12/26 Python
pytorch模型存储的2种实现方法
2020/02/14 Python
python爬虫使用正则爬取网站的实现
2020/08/03 Python
Python+Opencv身份证号码区域提取及识别实现
2020/08/25 Python
python关于倒排列的知识点总结
2020/10/13 Python
canvas因为图片资源不在同一域名下而导致的跨域污染画布的解决办法
2019/01/18 HTML / CSS
英国在线玫瑰专家:InterRose
2019/12/01 全球购物
幼师专业毕业生自荐信
2013/09/29 职场文书
护士实习生自我鉴定范文
2013/12/10 职场文书
演讲比赛的活动方案
2014/08/28 职场文书
英文导游词
2015/02/13 职场文书
2015年乡镇流动人口工作总结
2015/05/12 职场文书
《比尾巴》教学反思
2016/02/24 职场文书
Java生成日期时间存入Mysql数据库的实现方法
2022/03/03 Java/Android